home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #2 / Amiga Plus CD - 1995 - No. 2.iso / pd / grafik / mandelsquare-ham / mandelsquare_old.c < prev    next >
C/C++ Source or Header  |  1995-04-11  |  98KB  |  4,135 lines

  1. /** Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf `Olsen' Barthel, all rights reserved
  4.  *
  5.  *    Name .....: MandelSquare
  6.  *    Created ..: Monday 26-Aug-91 11:20
  7.  *    Revision .: 3
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    16-Sep-91    Olsen        Added animation replay feature
  12.  *    12-Sep-91    Olsen        Several enhancements & bug fixes
  13.  *    26-Aug-91    Olsen        Created this file!
  14.  *
  15.  ***************************************************************************/
  16.  
  17. #include "MandelSquare.h"
  18.  
  19. UBYTE VersTag[]    = VERSTAG;
  20.  
  21.     /* Menu IDs */
  22.  
  23. enum    {    MEN_OPEN=17,MEN_SAVE,MEN_SAVEAS,MEN_PRI0,MEN_PRI1,MEN_PRI2,MEN_PLAY,MEN_START,MEN_STOP,MEN_SCROLL,MEN_FRAME,MEN_INCLUDE,MEN_RESOLUTION,MEN_ABOUT,MEN_QUIT,
  24.         MEN_ZOOM,MEN_CLIP,MEN_RERUN,MEN_PRECISE,MEN_COORDS,MEN_PALETTE,MEN_SPEC,MEN_RUN };
  25.  
  26.     /* Screen width & height must be a multiple of 32. */
  27.  
  28. #define PLUS        32
  29.  
  30.     /* Dimensions of the coords control panel. */
  31.  
  32. #define COORDS_WIDTH    256
  33. #define COORDS_HEIGHT    120
  34.  
  35.     /* Dimensions of the palette control panel. */
  36.  
  37. #define PALETTE_WIDTH    245
  38. #define PALETTE_HEIGHT    53
  39.  
  40.     /* Dimensions of the scroll amount control panel. */
  41.  
  42. #define SCROLL_WIDTH    175
  43. #define SCROLL_HEIGHT    45
  44.  
  45.     /* Two handy macros to set the window mouse pointer. */
  46.  
  47. #define            SetWait(Window)        SetPointer((Window),&Stopwatch[0],16,16,-6,0)
  48. #define            SetClear(Window)    SetPointer((Window),&ClearData[0],1,16,0,0)
  49.  
  50.     /* Just to avoid enforcer hits... */
  51.  
  52. #define            BailOut()        if(!Gadget) return(NULL);
  53.  
  54.     /* In Plot.asm, Iterate.asm & WaitLine.asm */
  55.  
  56. extern VOID __asm    Plot(register __a0 struct BitMap *,register __d0 WORD X,register __d1 WORD Y,register __d2 WORD Colour);
  57. extern BYTE __asm    Test(register __a0 struct BitMap *,register __d0 WORD X,register __d1 WORD Y);
  58. extern VOID __asm    Set(register __a0 PLANEPTR *,register __d0 WORD X,register __d2 WORD Colour,register __d3 WORD Depth);
  59. extern BYTE __stdargs    Iterate(double RealValue,double ImaginaryValue);
  60. extern BYTE __stdargs    Iterate2(double RealValue,double ImaginaryValue);
  61. extern VOID __asm    WaitLine(register __d1 Line);
  62.  
  63. VOID __regargs        PlotHAM(struct BitMap *BitMap,WORD X,WORD Y,UBYTE Red,UBYTE Green,UBYTE Blue);
  64.  
  65.     /* In Mandelbrot.c */
  66.  
  67. VOID __regargs        DrawSquare(struct RastPort *RPort,WORD X,WORD Y,WORD Width);
  68. VOID __regargs        DrawLine(struct RastPort *RPort,UWORD FromX,UWORD FromY,UWORD ToX,UWORD ToY);
  69. VOID            IterationSetup(VOID);
  70. VOID            GetScreenPalette(VOID);
  71. LONG __saveds        CycleServer(VOID);
  72. VOID            GfxCleanup(VOID);
  73. LONG            GfxSetup(VOID);
  74. VOID __regargs        CloseAll(LONG ReturnCode);
  75. VOID            OpenAll(VOID);
  76. VOID __regargs        CopyLine(struct BitMap *BitMap,WORD Line);
  77. VOID            GetTime(VOID);
  78. VOID            BlockWindow(VOID);
  79. VOID            ReleaseWindow(VOID);
  80. BYTE            GetFile(UBYTE *Title,UBYTE *Directory,UBYTE *Name,UBYTE *Buffer,UBYTE *Pattern,BYTE SaveFlag);
  81. WORD __stdargs        MyEasyRequest(UBYTE *Gadgets,UBYTE *Text,...);
  82. VOID            FadeTo(struct ViewPort *VPort,UWORD *From,UWORD *To,UBYTE NumColours,UBYTE ToCol,UBYTE FromCol);
  83. ULONG __regargs        Random(LONG MaxValue);
  84. struct Gadget *        CreateAllCoordsGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  85. struct Gadget *        CreateAllPaletteGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  86. struct Gadget *        CreateAllScrollGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge);
  87. VOID            InfoText(VOID);
  88. WORD            CalculateFrames(double MinReal,double MinImaginary,double Size);
  89. VOID            RunAnim(VOID);
  90. VOID            StopAnim(VOID);
  91. VOID            Coords(VOID);
  92. VOID            Palette(VOID);
  93. VOID            MaxScrollPanel(VOID);
  94. VOID            AreaZoom(VOID);
  95. VOID            Zoom(VOID);
  96. VOID            HandleEvent(VOID);
  97. VOID            Mandelbrot(double MinReal,double MinImaginary,double RealStep,double ImaginaryStep,LONG Left,LONG Top,LONG Width,LONG Height);
  98. VOID            RunMandelbrot(double MinReal,double MaxReal,double MinImaginary,double MaxImaginary,LONG Width,LONG Height);
  99. VOID            RunAreaMandelbrot(double RealStep,double ImaginaryStep);
  100. VOID __stdargs        main(VOID);
  101.  
  102.     /* In playanim.lib */
  103.  
  104. VOID            ClosePreLoadIFF(VOID);
  105. BYTE            OpenPreLoadIFF(BPTR file);
  106. VOID            DeleteBuffer(VOID);
  107. BYTE            CreateBuffer(VOID);
  108. VOID            SwapBits(VOID);
  109. BYTE            PlayAnim(VOID);
  110.  
  111.     /* In saveanim.lib */
  112.  
  113. BYTE            AnimOpen(UBYTE *Name,struct ViewPort *VPort,struct RastPort *RPort);
  114. BYTE            AnimAdd(struct RastPort *RPort);
  115. VOID            AnimClose(VOID);
  116.  
  117.     /* In ReadILBM.c */
  118.  
  119. struct IFFHandle * __regargs    OpenImageFile(UBYTE *Name);
  120. VOID __regargs            CloseImageFile(struct IFFHandle *Handle);
  121. BYTE __regargs            ReadImageBody(struct IFFHandle *Handle,struct BitMap *BitMap,struct BitMapHeader *BitMapHeader);
  122. BYTE __regargs            ReadImageHeader(struct IFFHandle *Handle,ULONG *ViewModes,BYTE *NumCols,UWORD *Colours,struct BitMapHeader *BitMapHeader,struct MandelInfo *MandelInfo);
  123. VOID __regargs            DeleteBitMap(struct BitMap *BitMap);
  124. struct BitMap * __regargs    CreateBitMap(BYTE Depth,UWORD Width,UWORD Height);
  125.  
  126.     /* In WriteILBM.c */
  127.  
  128. LONG            SaveBitMap(struct BitMap *BitMap,struct ViewPort *VPort,LONG LeftEdge,LONG TopEdge,LONG Width,LONG Height,LONG ParentWidth,LONG ParentHeight,STRPTR Name,struct MandelInfo *MandelInfo);
  129.  
  130.     /* Shared and global library data. */
  131.  
  132. struct IntuitionBase    *IntuitionBase;
  133. struct GfxBase        *GfxBase;
  134. struct Library        *GadToolsBase;
  135. struct Library        *IFFParseBase;
  136. struct Library        *AslBase;
  137. struct Library        *TimerBase;
  138. struct Library        *IconBase;
  139.  
  140.     /* Timer data. */
  141.  
  142. struct timerequest    *TimeRequest;
  143. struct MsgPort        *TimePort;
  144.  
  145.     /* Window & Screen data. */
  146.  
  147. struct Screen        *Screen;
  148. struct Window        *Window;
  149. struct RastPort        *RPort;
  150. struct ViewPort        *VPort;
  151. APTR             VisualInfo;
  152. struct BitMap        *BackupBitMap;
  153. struct Menu        *Menu;
  154.  
  155.     /* Current process and Window Pointer. */
  156.  
  157. struct Process        *ThisProcess;
  158. APTR             OldPtr;
  159. BYTE             OldPri;
  160.  
  161.     /* Colour cycling data. */
  162.  
  163. struct Interrupt    *CycleInterrupt;
  164. BYTE             DoCycle = FALSE,Forward,Wheel = 0,Add = 0;
  165.  
  166.     /* Some strings. */
  167.  
  168. UBYTE             LastName[256],NameBuffer[256],DummyBuffer[256],AnimSaveName[256],AnimPlayName[256];
  169.  
  170.     /* Table of spectral colours. */
  171.  
  172. UWORD             Table[80];
  173.  
  174.     /* Some more colour tables. */
  175.  
  176. UWORD             ScreenPalette[32],SinPalette[32],WheelPalette[32];
  177.  
  178.     /* Calculation data. */
  179.  
  180. LONG             MaxIteration = 32;
  181. double             RealStep,ImaginaryStep;
  182. double             RealWidth = 4.5,ImaginaryHeight = 4.5;
  183. double             MinReal,MinImaginary;
  184. double             MainMinReal,MainMinImaginary,MainRealWidth,MainImaginaryHeight;
  185. double             MaxScroll = 4;
  186. double             LastSize,LastMinReal,LastMinImaginary;
  187.  
  188.     /* Size and position of the screen. */
  189.  
  190. UWORD             AreaLeft,AreaTop,AreaWidth,AreaHeight;
  191.  
  192.     /* Various flags. */
  193.  
  194. BYTE             Running = FALSE,NewCoords = FALSE,AreaActive = FALSE,GotClip = FALSE,
  195.              NewMode = FALSE,Frame = FALSE,Include = TRUE,Faster = TRUE,UseWheel = FALSE,
  196.              Precise = FALSE,HoldIt = FALSE,AnimRunning = FALSE,FullPicture,AnimOpened = FALSE;
  197.  
  198.     /* A range of colour intensities and the colour transition table. */
  199.  
  200. BYTE             Range[32],*Wave;
  201.  
  202.     /* The levels of the palette colour sliders. */
  203.  
  204. BYTE             RedLevel = 27,GreenLevel = 22,BlueLevel = 17;
  205.  
  206.     /* A global MandelInfo structure to be prepared for the
  207.      * MAND chunk.
  208.      */
  209.  
  210. struct MandelInfo     MandelInfo;
  211.  
  212.     /* Rendering data. */
  213.  
  214. LONG              Mode = LORES_KEY,Depth = 5,Square = 256;
  215.  
  216.     /* The TextFont structure contained in Font.c */
  217.  
  218. extern struct TextFont     DigitFont;
  219.  
  220.     /* A single line bitmap whose planes are to be located
  221.      * in fast ram.
  222.      */
  223.  
  224. struct BitMap         LineBitMap;
  225.  
  226.     /* Global image data. */
  227.  
  228. struct BitMap        *GlobalBitMap;
  229. struct BitMapHeader     GlobalHeader;
  230. ULONG             GlobalMode;
  231.  
  232.     /* The initial colour table the program uses. */
  233.  
  234. UWORD ColourTable[32] =
  235. {
  236.     0x0000,0x0FFF,0x04BE,0x03AE,
  237.     0x019D,0x007D,0x016C,0x034B,
  238.     0x043A,0x0619,0x0707,0x0916,
  239.     0x0A34,0x0B43,0x0C61,0x0D70,
  240.     0x0D91,0x0EA3,0x0EB4,0x0FC6,
  241.     0x0FD7,0x0FD9,0x0EEA,0x0EEB,
  242.     0x0DFC,0x0DFD,0x0CFD,0x0BEE,
  243.     0x0AEE,0x09DF,0x07DF,0x06CF
  244. };
  245.  
  246.     /* The standard font to be use throughout the
  247.      * whole program.
  248.      */
  249.  
  250. struct TextAttr DefaultFont =
  251. {
  252.     (UBYTE *)"topaz.font",
  253.     8,
  254.     FS_NORMAL,
  255.     FPF_ROMFONT
  256. };
  257.  
  258.     /* Definitions for the pull-down menu used by the program. */
  259.  
  260. struct NewMenu MandelbrotMenu[] =
  261. {
  262.     { NM_TITLE, "Project",             0 , 0,            0,    (APTR)0},
  263.     {  NM_ITEM, "Open Picture...",        "O", 0,            0,    (APTR)MEN_OPEN},
  264.     {  NM_ITEM, "Save Picture",         0 , 0,            0,    (APTR)MEN_SAVE},
  265.     {  NM_ITEM, "Save Picture As...",    "S", 0,            0,    (APTR)MEN_SAVEAS},
  266.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  267.     {  NM_ITEM, "Priority",             0 , 0,            0,    (APTR)0},
  268.     {   NM_SUB, "-5",             0 , CHECKIT|MENUTOGGLE,~1,    (APTR)MEN_PRI0},
  269.     {   NM_SUB, " 0",             0 , CHECKIT|CHECKED|MENUTOGGLE,~2,    (APTR)MEN_PRI1},
  270.     {   NM_SUB, "+5",             0 , CHECKIT|MENUTOGGLE,~4,    (APTR)MEN_PRI2},
  271.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  272.     {  NM_ITEM, "Replay Animation...",    "!", 0,            0,    (APTR)MEN_PLAY},
  273.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  274.     {  NM_ITEM, "Begin Animation...",    "B", 0,            0,    (APTR)MEN_START},
  275.     {  NM_ITEM, "End Animation",        "E", 0,            0,    (APTR)MEN_STOP},
  276.     {  NM_ITEM, "Set Scroll Amount...",    "A", 0,            0,    (APTR)MEN_SCROLL},
  277.     {  NM_ITEM, "Include Frame",         0 , CHECKIT|MENUTOGGLE,0,    (APTR)MEN_FRAME},
  278.     {  NM_ITEM, "Include Coordinates",     0 , CHECKIT|CHECKED|MENUTOGGLE,0,    (APTR)MEN_INCLUDE},
  279.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  280.     {  NM_ITEM, "Change Resolution",    "X", 0,            0,    (APTR)MEN_RESOLUTION},
  281.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  282.     {  NM_ITEM, "About...",            "?", 0,            0,    (APTR)MEN_ABOUT},
  283.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  284.     {  NM_ITEM, "Quit...",            "Q", 0,            0,    (APTR)MEN_QUIT},
  285.  
  286.     { NM_TITLE, "Calculation",         0 , 0,            0,    (APTR)0},
  287.     {  NM_ITEM, "Magnify...",        "M", 0,            0,    (APTR)MEN_ZOOM},
  288.     {  NM_ITEM, "Detail...",        "D", 0,            0,    (APTR)MEN_CLIP},
  289.     {  NM_ITEM, "Recalculate...",        "R", 0,            0,    (APTR)MEN_RERUN},
  290.     {  NM_ITEM, "Precise Calculation",     0 , CHECKIT|MENUTOGGLE,0,    (APTR)MEN_PRECISE},
  291.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  292.     {  NM_ITEM, "Coordinates...",        "C", 0,            0,    (APTR)MEN_COORDS},
  293.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  294.     {  NM_ITEM, "Palette...",        "P", 0,            0,    (APTR)MEN_PALETTE},
  295.     {  NM_ITEM, "Spectral Colours",         0 , CHECKIT|MENUTOGGLE,0,    (APTR)MEN_SPEC},
  296.     {  NM_ITEM, NM_BARLABEL,         0 , 0,            0,    (APTR)0},
  297.     {  NM_ITEM, "Toggle Calculation",    ".", 0,            0,    (APTR)MEN_RUN},
  298.  
  299.     { NM_TITLE, "Depth",             0 , 0,            0,    (APTR)0},
  300.     {  NM_ITEM, "   32",            "0", CHECKIT|CHECKED,    ~  1,    (APTR)5},
  301.     {  NM_ITEM, "   64",            "1", CHECKIT,        ~  2,    (APTR)6},
  302.     {  NM_ITEM, "  128",            "2", CHECKIT,        ~  4,    (APTR)7},
  303.     {  NM_ITEM, "  256",            "3", CHECKIT,        ~  8,    (APTR)8},
  304.     {  NM_ITEM, "  512",            "4", CHECKIT,        ~ 16,    (APTR)9},
  305.     {  NM_ITEM, " 1024",            "5", CHECKIT,        ~ 32,    (APTR)10},
  306.     {  NM_ITEM, " 2048",            "6", CHECKIT,        ~ 64,    (APTR)11},
  307.     {  NM_ITEM, " 4096",            "7", CHECKIT,        ~128,    (APTR)12},
  308.     {  NM_ITEM, " 8192",            "8", CHECKIT,        ~256,    (APTR)13},
  309.     {  NM_ITEM, "16384",            "9", CHECKIT,        ~512,    (APTR)14},
  310.     {   NM_END, 0,                 0 , 0,            0,    (APTR)0}
  311. };
  312.  
  313.     /* Run-dump of the stopwatch mouse pointer. */
  314.  
  315. UWORD __chip Stopwatch[(2 + 16) * 2] =
  316. {
  317.     0x0000,0x0000,
  318.  
  319.     0x0400,0x07C0,
  320.     0x0000,0x07C0,
  321.     0x0100,0x0380,
  322.     0x0000,0x07E0,
  323.     0x07C0,0x1FF8,
  324.     0x1FF0,0x3FEC,
  325.     0x3FF8,0x7FDE,
  326.     0x3FF8,0x7FBE,
  327.     0x7FFC,0xFF7F,
  328.     0x7EFC,0xFFFF,
  329.     0x7FFC,0xFFFF,
  330.     0x3FF8,0x7FFE,
  331.     0x3FF8,0x7FFE,
  332.     0x1FF0,0x3FFC,
  333.     0x07C0,0x1FF8,
  334.     0x0000,0x07E0,
  335.  
  336.     0x0000,0x0000
  337. };
  338.  
  339.     /* Definitions for a clear sprite. */
  340.  
  341. UWORD __chip ClearData[(2 + 1) * 2] =
  342. {
  343.     0x0000,0x0000,
  344.  
  345.     0x0000,0x0000,
  346.  
  347.     0x0000,0x0000
  348. };
  349.  
  350.     /* Run-dump of the picture icon image data. */
  351.  
  352. USHORT Picture1Data[700] =
  353. {
  354.     0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000,0x0000,
  355.     0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  356.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  357.     0x0030,0x0000,0x0000,0x0000,0x4000,0x0030,0x0000,0x0000,
  358.     0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0400,0x0030,
  359.     0x0000,0x0000,0x0000,0x1C00,0x0030,0x0000,0x0000,0x0000,
  360.     0x0000,0x0030,0x0000,0x0000,0x0000,0x4800,0x0030,0x0000,
  361.     0x0000,0x0000,0xC000,0x0030,0x0000,0x0000,0x0005,0x8000,
  362.     0x0030,0x0000,0x0000,0x0001,0x0300,0x0030,0x0000,0x0000,
  363.     0x0001,0x0200,0x0030,0x0000,0x0000,0x0001,0x0200,0x0030,
  364.     0x0000,0x0000,0x0100,0x0020,0x0030,0x0000,0x0000,0x002F,
  365.     0x8E80,0x8030,0x0000,0x0000,0x0328,0x0080,0x0030,0x0000,
  366.     0x0000,0x0260,0x002E,0xC030,0x0000,0x0000,0x0200,0x0008,
  367.     0x8030,0x0000,0x0000,0x0200,0x0000,0x8030,0x0000,0x0000,
  368.     0x1600,0x0000,0x0030,0x0000,0x0000,0x1400,0x0000,0x8030,
  369.     0x0000,0x2000,0x1000,0x0000,0x0030,0x0000,0x0040,0x3000,
  370.     0x0000,0x9030,0x0000,0x4000,0x2000,0x0000,0x3030,0x0000,
  371.     0x0080,0x6000,0x0000,0x6030,0x0000,0x0FB0,0x4000,0x0000,
  372.     0x0030,0x0000,0x0800,0xC000,0x0000,0x2030,0x0000,0x0800,
  373.     0x0000,0x0000,0x6030,0x0000,0x1800,0xC000,0x0000,0x4030,
  374.     0x0000,0x3000,0x8000,0x0000,0x4030,0x0001,0x2000,0x8000,
  375.     0x0000,0xC030,0x0003,0x6000,0x0000,0x0000,0x8030,0x0F82,
  376.     0x0000,0x0000,0x0001,0x0030,0x0020,0x0000,0x0000,0x0000,
  377.     0x0030,0x0008,0x0000,0x0000,0x0000,0x0030,0x0000,0x2000,
  378.     0x0000,0x0000,0x0030,0x0003,0x8000,0x8000,0x0000,0x4030,
  379.     0x0006,0x0000,0x8000,0x0000,0x4030,0x0000,0x4800,0x0000,
  380.     0x0000,0x0030,0x0000,0x0802,0x4000,0x0000,0x2030,0x0000,
  381.     0x0006,0x4000,0x0000,0x6030,0x0000,0x060C,0x0000,0x0000,
  382.     0x0030,0x0000,0x3C78,0x0000,0x0000,0x0030,0x0000,0x20C0,
  383.     0x0000,0x0000,0x1030,0x0000,0x2000,0x1800,0x0000,0xF030,
  384.     0x0000,0x4000,0x0000,0x0001,0x8030,0x0000,0x0000,0x2000,
  385.     0x0001,0x0030,0x0000,0x0000,0x0200,0x0000,0x0030,0x0000,
  386.     0x0000,0x0200,0x0000,0x0030,0x0000,0x0000,0x0200,0x0000,
  387.     0x4030,0x0000,0x0000,0x0080,0x003E,0xC030,0x0000,0x0000,
  388.     0x0180,0x0120,0x8030,0x0000,0x0000,0x0D19,0x8360,0x8030,
  389.     0x0000,0x0000,0x0101,0x0200,0x0030,0x0000,0x0000,0x0001,
  390.     0x0200,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  391.     0x0000,0x0000,0x0300,0x0030,0x0000,0x0000,0x0005,0x0E00,
  392.     0x0030,0x0000,0x0000,0x0001,0x1800,0x0030,0x0000,0x0000,
  393.     0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x2000,0x0030,
  394.     0x0000,0x0000,0x0000,0x2C00,0x0030,0x0000,0x0000,0x0000,
  395.     0x2000,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  396.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  397.     0x0030,0x7FFF,0xFFFF,0xFFFF,0xFFFF,0xFFF0,
  398.  
  399.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFE0,0xD555,0x5555,0x5555,
  400.     0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,0x5540,0xD555,
  401.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  402.     0x5540,0xD555,0x5555,0x5555,0x1555,0x5540,0xD555,0x5555,
  403.     0x5555,0x3555,0x5540,0xD555,0x5555,0x5555,0x8155,0x5540,
  404.     0xD555,0x5555,0x5555,0x8155,0x5540,0xD555,0x5555,0x5557,
  405.     0x0555,0x5540,0xD555,0x5555,0x555C,0x0555,0x5540,0xD555,
  406.     0x5555,0x5550,0x0155,0x5540,0xD555,0x5555,0x5558,0x5155,
  407.     0x5540,0xD555,0x5555,0x5558,0x5855,0x5540,0xD555,0x5555,
  408.     0x7558,0x59D5,0x5540,0xD555,0x5555,0x6DF8,0x7197,0x5540,
  409.     0xD555,0x5555,0x6080,0x401E,0x5540,0xD555,0x5555,0x4000,
  410.     0x5010,0x5540,0xD555,0x5555,0x5015,0x5500,0x5540,0xD555,
  411.     0x5555,0x5115,0x5540,0x1540,0xD555,0x5555,0xF155,0x5554,
  412.     0x5540,0xD555,0x5555,0x8155,0x5551,0x5540,0xD555,0xD555,
  413.     0x8155,0x5554,0x5540,0xD555,0x1555,0x8155,0x5556,0x5540,
  414.     0xD555,0x9755,0x8555,0x5554,0x1540,0xD555,0x1E35,0x0555,
  415.     0x5555,0x0540,0xD555,0x0005,0x1555,0x5555,0x0540,0xD555,
  416.     0x4005,0x1555,0x5555,0x1540,0xD555,0xC040,0x1555,0x5555,
  417.     0x1540,0xD555,0x0550,0x1555,0x5555,0x1540,0xD555,0x8554,
  418.     0x5555,0x5555,0x1540,0xD55B,0x8556,0x1555,0x5557,0x1540,
  419.     0xD558,0x0554,0x5555,0x5556,0x1540,0xFFF0,0x1555,0x5555,
  420.     0x5554,0x1540,0xC000,0x1555,0x5555,0x555D,0x5540,0xD001,
  421.     0x5555,0x5555,0x5550,0x5540,0xD541,0xD555,0x5555,0x5555,
  422.     0x5540,0xD550,0x1557,0x5555,0x5554,0x5540,0xD558,0x1556,
  423.     0x5555,0x5555,0x5540,0xD550,0x1556,0x5555,0x5555,0x1540,
  424.     0xD551,0x055C,0x5555,0x5555,0x1540,0xD555,0x05F0,0x5555,
  425.     0x5555,0x9540,0xD555,0x4580,0x1555,0x5555,0x1540,0xD555,
  426.     0xC000,0x1555,0x5555,0x1540,0xD555,0x8001,0x1555,0x5555,
  427.     0x9540,0xD555,0x0005,0x1555,0x5557,0x1540,0xD555,0x1515,
  428.     0x8555,0x5556,0x0540,0xD555,0x5555,0x8555,0x555C,0x0540,
  429.     0xD555,0x1555,0x0555,0x5550,0x5540,0xD555,0x5555,0x4155,
  430.     0x5574,0x5540,0xD555,0x5555,0x5155,0x5564,0x5540,0xD555,
  431.     0x5555,0x7155,0x55C6,0x5540,0xD555,0x5555,0x403D,0x5F80,
  432.     0x1540,0xD555,0x5555,0x7001,0x5800,0x1540,0xD555,0x5555,
  433.     0x4040,0x5014,0x5540,0xD555,0x5555,0x5040,0x5015,0x5540,
  434.     0xD555,0x5555,0x5458,0x5955,0x5540,0xD555,0x5555,0x5558,
  435.     0x5955,0x5540,0xD555,0x5555,0x5558,0x7155,0x5540,0xD555,
  436.     0x5555,0x5550,0x6055,0x5540,0xD555,0x5555,0x5550,0x0155,
  437.     0x5540,0xD555,0x5555,0x5554,0x0555,0x5540,0xD555,0x5555,
  438.     0x5555,0x8555,0x5540,0xD555,0x5555,0x5555,0x8555,0x5540,
  439.     0xD555,0x5555,0x5555,0x1155,0x5540,0xD555,0x5555,0x5555,
  440.     0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,0x5540,0xD555,
  441.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  442.     0x5540,0x8000,0x0000,0x0000,0x0000,0x0000
  443. };
  444.  
  445.     /* Definitions for the picture icon image. */
  446.  
  447. struct Image Picture1Image =
  448. {
  449.     0,0,
  450.     76,70,2,
  451.     (USHORT *)&Picture1Data[0],
  452.     0x03,0x00,
  453.     (struct Image *)NULL
  454. };
  455.  
  456.     /* Tool types for the picture project icon. */
  457.  
  458. char *PictureToolTypes[] =
  459. {
  460.     "FILETYPE=ILBM",
  461.     NULL
  462. };
  463.  
  464.     /* The name of the project's default tool (will be filled
  465.      * in later).
  466.      */
  467.  
  468. UBYTE DefaultTool[256];
  469.  
  470.     /* Definitions for the picture project icon. */
  471.  
  472. struct DiskObject PictureIcon =
  473. {
  474.     WB_DISKMAGIC,
  475.     WB_DISKVERSION,
  476.  
  477.     (struct Gadget *)NULL,
  478.     0,0,
  479.     76,70,
  480.     0x0004,
  481.     0x0003,
  482.     0x0001,
  483.     (APTR)&Picture1Image,
  484.     (APTR)NULL,
  485.     (struct IntuiText *)NULL,
  486.     NULL,
  487.     (APTR)NULL,
  488.     NULL,
  489.     (APTR)NULL,
  490.  
  491.     WBPROJECT,
  492.     (char *)NULL,
  493.     PictureToolTypes,
  494.     NO_ICON_POSITION,
  495.     NO_ICON_POSITION,
  496.     (struct DrawerData *)NULL,
  497.     (char *)NULL,
  498.     20000
  499. };
  500.  
  501.     /* Run-dump of the anim icon image data. */
  502.  
  503. UWORD Anim1Data[700] =
  504. {
  505.     0x0000,0x0000,0x0000,0x0000,0x0010,0x0000,0x0000,0x0000,
  506.     0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  507.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  508.     0x0030,0x0000,0x0000,0x0000,0x4000,0x0030,0x0000,0x0000,
  509.     0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0400,0x0030,
  510.     0x0000,0x0000,0x0000,0x1C00,0x0030,0x0000,0x0000,0x0000,
  511.     0x0000,0x0030,0x0000,0x0000,0x0000,0x4800,0x0030,0x0000,
  512.     0x0000,0x0000,0xC000,0x0030,0x0000,0x0000,0x0005,0x8000,
  513.     0x0030,0x0000,0x0000,0x0001,0x0300,0x0030,0x0000,0x0000,
  514.     0x0001,0x0200,0x0030,0x0000,0x0000,0x0001,0x0200,0x0030,
  515.     0x0000,0x0000,0x0100,0x0020,0x0030,0x0000,0x0000,0x002F,
  516.     0x8E80,0x8030,0x0000,0x0000,0x0328,0x0080,0x0030,0x0000,
  517.     0x0000,0x0260,0x002E,0xC030,0x0003,0xFFD0,0x0200,0x0008,
  518.     0x8030,0x0002,0x0010,0x0200,0x0000,0x8030,0x0002,0x0010,
  519.     0x1600,0x0000,0x0030,0x0002,0x0010,0x1400,0x0000,0x8030,
  520.     0x0002,0x2010,0x1000,0x0000,0x0030,0x0002,0x0010,0x3000,
  521.     0x0000,0x9030,0x0002,0x4010,0x2000,0x0000,0x3030,0x0002,
  522.     0x0010,0x6000,0x0000,0x6030,0x0002,0x0F10,0x4000,0x0000,
  523.     0x0030,0x0002,0x0810,0xC000,0x0000,0x2030,0x0002,0x0810,
  524.     0x0000,0x0000,0x6030,0x0002,0x0010,0xC000,0x0000,0x4030,
  525.     0x0000,0x0010,0x8000,0x0000,0x4030,0x0003,0xFFF0,0x8000,
  526.     0x0000,0xC030,0x0003,0x6000,0x0000,0x0000,0x8030,0x0F82,
  527.     0x0000,0x0000,0x0001,0x0030,0x0020,0x0000,0x0000,0x0000,
  528.     0x0030,0x0008,0x0000,0x0000,0x0000,0x0030,0x0000,0x2000,
  529.     0x0000,0x0000,0x0030,0x0003,0x8000,0x8000,0x0000,0x4030,
  530.     0x0006,0x0000,0x8000,0x0000,0x4030,0x0000,0x4800,0x0000,
  531.     0x0000,0x0030,0x0000,0x0802,0x4000,0x0000,0x2030,0x0000,
  532.     0x0006,0x4000,0x0000,0x6030,0x0000,0x060C,0x0000,0x0000,
  533.     0x0030,0x0000,0x3C78,0x0000,0x0000,0x0030,0x0000,0x20C0,
  534.     0x0000,0x0000,0x1030,0x0000,0x2000,0x1800,0x0000,0xF030,
  535.     0x0000,0x400C,0x0000,0x0C01,0x8030,0x0000,0x001C,0x2000,
  536.     0x1E01,0x0030,0x0000,0x001C,0x0200,0x0C00,0x0030,0x0000,
  537.     0x001E,0x0200,0x0000,0x0030,0x0000,0x003E,0x0DF0,0x7C1F,
  538.     0xF830,0x0000,0x003E,0x0FF8,0xFC1F,0xFC30,0x0000,0x0037,
  539.     0x0F18,0x0D1D,0xCC30,0x0000,0x0073,0x0E19,0x8D59,0xCC30,
  540.     0x0000,0x0073,0x0E19,0x0C19,0xCC30,0x0000,0x0063,0x8C19,
  541.     0x0C19,0xCC30,0x0000,0x00E1,0x8C18,0x0C19,0xCC30,0x0000,
  542.     0x00FF,0x8C18,0x0D19,0xCC30,0x0000,0x00FF,0xCC19,0x0C19,
  543.     0xCC30,0x0000,0x01C1,0xCC19,0x0C19,0xCC30,0x0000,0x01C0,
  544.     0xCC18,0x0C19,0xCC30,0x0000,0x0180,0xEC18,0x2C19,0xCC30,
  545.     0x0000,0x0180,0xEC18,0x2C19,0xCC30,0x0000,0x0100,0x6C18,
  546.     0x2C18,0x8C30,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,
  547.     0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,0x0000,0x0000,
  548.     0x0030,0x7FFF,0xFFFF,0xFFFF,0xFFFF,0xFFF0,
  549.  
  550.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFE0,0xD555,0x5555,0x5555,
  551.     0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,0x5540,0xD555,
  552.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  553.     0x5540,0xD555,0x5555,0x5555,0x1555,0x5540,0xD555,0x5555,
  554.     0x5555,0x3555,0x5540,0xD555,0x5555,0x5555,0x8155,0x5540,
  555.     0xD555,0x5555,0x5555,0x8155,0x5540,0xD555,0x5555,0x5557,
  556.     0x0555,0x5540,0xD555,0x5555,0x555C,0x0555,0x5540,0xD555,
  557.     0x5555,0x5550,0x0155,0x5540,0xD555,0x5555,0x5558,0x5155,
  558.     0x5540,0xD555,0x5555,0x5558,0x5855,0x5540,0xD555,0x5555,
  559.     0x7558,0x59D5,0x5540,0xD555,0x5555,0x6DF8,0x7197,0x5540,
  560.     0xD555,0x5555,0x6080,0x401E,0x5540,0xD555,0x5555,0x4000,
  561.     0x5010,0x5540,0xD55F,0xFFC5,0x5015,0x5500,0x5540,0xD558,
  562.     0x0005,0x5115,0x5540,0x1540,0xD558,0x0005,0xF155,0x5554,
  563.     0x5540,0xD559,0x5545,0x8155,0x5551,0x5540,0xD559,0xD545,
  564.     0x8155,0x5554,0x5540,0xD559,0x1545,0x8155,0x5556,0x5540,
  565.     0xD559,0x9745,0x8555,0x5554,0x1540,0xD559,0x1E45,0x0555,
  566.     0x5555,0x0540,0xD559,0x0045,0x1555,0x5555,0x0540,0xD559,
  567.     0x4045,0x1555,0x5555,0x1540,0xD559,0xC040,0x1555,0x5555,
  568.     0x1540,0xD559,0x0540,0x1555,0x5555,0x1540,0xD559,0x8544,
  569.     0x5555,0x5555,0x1540,0xD559,0xFFC6,0x1555,0x5557,0x1540,
  570.     0xD550,0x0004,0x5555,0x5556,0x1540,0xFFF0,0x0005,0x5555,
  571.     0x5554,0x1540,0xC000,0x1555,0x5555,0x555D,0x5540,0xD001,
  572.     0x5555,0x5555,0x5550,0x5540,0xD541,0xD555,0x5555,0x5555,
  573.     0x5540,0xD550,0x1557,0x5555,0x5554,0x5540,0xD558,0x1556,
  574.     0x5555,0x5555,0x5540,0xD550,0x1556,0x5555,0x5555,0x1540,
  575.     0xD551,0x055C,0x5555,0x5555,0x1540,0xD555,0x05F0,0x5555,
  576.     0x5555,0x9540,0xD555,0x4580,0x1555,0x5555,0x1540,0xD555,
  577.     0xC000,0x1555,0x5555,0x1540,0xD555,0x8001,0x1555,0x5555,
  578.     0x9540,0xD555,0x0005,0x1555,0x5557,0x1540,0xD555,0x1515,
  579.     0x8555,0x5556,0x0540,0xD555,0x5551,0x8555,0x515C,0x0540,
  580.     0xD555,0x1545,0x0555,0x4150,0x5540,0xD555,0x5551,0x4155,
  581.     0x5274,0x5540,0xD555,0x5551,0x5155,0x4D64,0x5540,0xD555,
  582.     0x5542,0x7005,0x01C0,0x0540,0xD555,0x5528,0x4D15,0x7D9C,
  583.     0xC140,0xD555,0x5528,0x6248,0x8002,0x1140,0xD555,0x5505,
  584.     0x4100,0x0005,0x0140,0xD555,0x5550,0x4040,0x4001,0x4140,
  585.     0xD555,0x5550,0x4240,0x4141,0x4140,0xD555,0x5502,0x8140,
  586.     0x4141,0x4140,0xD555,0x54A0,0x0140,0x6141,0x4140,0xD555,
  587.     0x5480,0x0140,0x6041,0x4140,0xD555,0x543F,0x4140,0x0141,
  588.     0x4140,0xD555,0x5501,0x0140,0x0141,0x4140,0xD555,0x5554,
  589.     0x0141,0x8141,0x4140,0xD555,0x5414,0xA141,0x8141,0x4140,
  590.     0xD555,0x5414,0x8141,0x0141,0x4140,0xD555,0x5555,0x6D59,
  591.     0x4D58,0x8D40,0xD555,0x5455,0x1145,0x5145,0x5140,0xD555,
  592.     0x5555,0x5555,0x5555,0x5540,0xD555,0x5555,0x5555,0x5555,
  593.     0x5540,0x8000,0x0000,0x0000,0x0000,0x0000
  594. };
  595.  
  596.     /* Definitions for the anim icon image. */
  597.  
  598. struct Image Anim1Image =
  599. {
  600.     0,0,
  601.     76,70,2,
  602.     (UWORD *)&Anim1Data[0],
  603.     0x03,0x00,
  604.     (struct Image *)NULL
  605. };
  606.  
  607.     /* Tool types for the anim project icon. */
  608.  
  609. char *AnimToolTypes[] =
  610. {
  611.     "FILETYPE=ANIM",
  612.     NULL
  613. };
  614.  
  615.     /* Definitions for the anim project icon. */
  616.  
  617. struct DiskObject AnimIcon =
  618. {
  619.     WB_DISKMAGIC,
  620.     WB_DISKVERSION,
  621.  
  622.     (struct Gadget *)NULL,
  623.     23,15,
  624.     76,70,
  625.     0x0004,
  626.     0x0003,
  627.     0x0001,
  628.     (APTR)&Anim1Image,
  629.     (APTR)NULL,
  630.     (struct IntuiText *)NULL,
  631.     NULL,
  632.     (APTR)NULL,
  633.     NULL,
  634.     (APTR)NULL,
  635.  
  636.     WBPROJECT,
  637.     (char *)NULL,
  638.     AnimToolTypes,
  639.     NO_ICON_POSITION,
  640.     NO_ICON_POSITION,
  641.     (struct DrawerData *)NULL,
  642.     (char *)NULL,
  643.     20000
  644. };
  645.  
  646.     /* DrawSquare():
  647.      *
  648.      *    Draws a square rectangle at a given position.
  649.      */
  650.  
  651. VOID __regargs
  652. DrawSquare(struct RastPort *RPort,WORD X,WORD Y,WORD Width)
  653. {
  654.     Move(RPort,X,Y);
  655.     Draw(RPort,X + Width - 1,Y);
  656.     Draw(RPort,X + Width - 1,Y + Width - 1);
  657.     Draw(RPort,X,Y + Width - 1);
  658.     Draw(RPort,X,Y);
  659. }
  660.  
  661.     /* DrawLine():
  662.      *
  663.      *    Draw a simple line from a to b.
  664.      */
  665.  
  666. VOID __regargs
  667. DrawLine(struct RastPort *RPort,UWORD FromX,UWORD FromY,UWORD ToX,UWORD ToY)
  668. {
  669.     Move(RPort,FromX,FromY);
  670.     Draw(RPort,ToX,ToY);
  671. }
  672.  
  673.     /* IterationSetup():
  674.      *
  675.      *    Sets up the iterations menu, checkmarks the currently
  676.      *    selected number of iterations, uncheckmarks all the
  677.      *    others.
  678.      */
  679.  
  680. VOID
  681. IterationSetup()
  682. {
  683.     struct MenuItem *Item;
  684.  
  685.     Window -> Flags |= WFLG_RMBTRAP;
  686.  
  687.     if(Item = ItemAddress(Menu,FULLMENUNUM(2,0,0)))
  688.     {
  689.         while(Item)
  690.         {
  691.             if((1 << (ULONG)GTMENUITEM_USERDATA(Item)) == MaxIteration)
  692.                 Item -> Flags |= CHECKED;
  693.             else
  694.                 Item -> Flags &= ~CHECKED;
  695.  
  696.             Item = Item -> NextItem;
  697.         }
  698.     }
  699.  
  700.     Window -> Flags &= ~WFLG_RMBTRAP;
  701. }
  702.  
  703.     /* GetScreenPalette():
  704.      *
  705.      *    Copies the current screen palette to a buffer.
  706.      */
  707.  
  708. VOID
  709. GetScreenPalette()
  710. {
  711.     WORD i;
  712.  
  713.     for(i = 0 ; i < 32 ; i++)
  714.         ScreenPalette[i] = GetRGB4(VPort -> ColorMap,i);
  715. }
  716.  
  717.     /* CycleServer():
  718.      *
  719.      *    The interrupt server routine which handles the
  720.      *    colour cycling.
  721.      */
  722.  
  723. LONG __saveds
  724. CycleServer()
  725. {
  726.     STATIC BYTE Count = 0;
  727.  
  728.     if(Count++ == 2)
  729.     {
  730.         if(DoCycle && !HoldIt)
  731.         {
  732.             if(UseWheel)
  733.             {
  734.                 BYTE AltWheel = Wheel,i;
  735.  
  736.                 WheelPalette[0] = 0x000;
  737.                 WheelPalette[1] = 0xFFF;
  738.  
  739.                 if(Forward)
  740.                 {
  741.                     for(i = 2 ; i < 32 ; i++)
  742.                     {
  743.                         WheelPalette[i] = Table[AltWheel];
  744.  
  745.                         AltWheel = (AltWheel + 1) % 75;
  746.                     }
  747.  
  748.                     Wheel = (Wheel + 1) % 75;
  749.                 }
  750.                 else
  751.                 {
  752.                     for(i = 2 ; i < 32 ; i++)
  753.                     {
  754.                         WheelPalette[i] = Table[AltWheel];
  755.  
  756.                         AltWheel = (AltWheel + 1) % 75;
  757.                     }
  758.  
  759.                     if(Wheel)
  760.                         Wheel--;
  761.                     else
  762.                         Wheel = 74;
  763.                 }
  764.  
  765.                 LoadRGB4(VPort,WheelPalette,1 << Depth);
  766.             }
  767.             else
  768.             {
  769.                 UWORD        NewPalette[32];
  770.                 BYTE        i,Wrap = (1 << Depth) - 2,AltAdd = Add;
  771.  
  772.                 NewPalette[0] = 0x000;
  773.                 NewPalette[1] = 0xFFF;
  774.  
  775.                 if(Forward)
  776.                 {
  777.                     for(i = 2 ; i < (1 << Depth) ; i++)
  778.                     {
  779.                         NewPalette[i] = SinPalette[AltAdd + 2];
  780.  
  781.                         AltAdd = (AltAdd + 1) % Wrap;
  782.                     }
  783.  
  784.                     Add = (Add + 1) % Wrap;
  785.                 }
  786.                 else
  787.                 {
  788.                     for(i = 2 ; i < (1 << Depth) ; i++)
  789.                     {
  790.                         NewPalette[i] = SinPalette[AltAdd + 2];
  791.  
  792.                         AltAdd = (AltAdd + 1) % Wrap;
  793.                     }
  794.  
  795.                     if(Add)
  796.                         Add--;
  797.                     else
  798.                         Add = Wrap - 1;
  799.                 }
  800.  
  801.                 LoadRGB4(VPort,NewPalette,1 << Depth);
  802.             }
  803.         }
  804.  
  805.         Count = 0;
  806.     }
  807.  
  808.     return(0);
  809. }
  810.  
  811.     /* GfxCleanup():
  812.      *
  813.      *    Frees the graphics resources allocated by the
  814.      *    program.
  815.      */
  816.  
  817. VOID
  818. GfxCleanup()
  819. {
  820.     ThisProcess -> pr_WindowPtr = OldPtr;
  821.  
  822.     if(LineBitMap . Planes[0])
  823.     {
  824.         FreeVec(LineBitMap . Planes[0]);
  825.  
  826.         LineBitMap . Planes[0] = NULL;
  827.     }
  828.  
  829.     DoCycle = FALSE;
  830.  
  831.     Delay(5);
  832.  
  833.     if(Screen)
  834.         ScreenToBack(Screen);
  835.  
  836.     if(Window)
  837.     {
  838.         ClearMenuStrip(Window);
  839.  
  840.         CloseWindow(Window);
  841.  
  842.         Window = NULL;
  843.     }
  844.  
  845.     if(Menu)
  846.     {
  847.         FreeMenus(Menu);
  848.  
  849.         Menu = NULL;
  850.     }
  851.  
  852.     if(VisualInfo)
  853.     {
  854.         FreeVisualInfo(VisualInfo);
  855.  
  856.         VisualInfo = NULL;
  857.     }
  858.  
  859.     if(Screen)
  860.     {
  861.         CloseScreen(Screen);
  862.  
  863.         Screen = NULL;
  864.     }
  865. }
  866.  
  867.     /* GfxSetup():
  868.      *
  869.      *    Allocates the graphics resources the program requires.
  870.      */
  871.  
  872. LONG
  873. GfxSetup()
  874. {
  875.     struct Rectangle     DisplayClip;
  876.     LONG             Differ;
  877.     WORD             i,c = 0,r = 15,g = 0,b = 0;
  878.     double             a,p;
  879.     BYTE             AltWheel = Wheel,Wrap = (1 << Depth) - 2;
  880.  
  881.     struct ColorSpec    *ColorSpec;
  882.  
  883.     a = PI / (double)((1 << Depth) - 2);
  884.  
  885.         /* Build a range of colour intensities mapped to the
  886.          * sine wave amplitude.
  887.          */
  888.  
  889.     for(p = 0.0, i = 0 ; (p < PI) && (i < (1 << Depth) - 2) ; p += a, i++)
  890.         Range[i] = (BYTE)(sin(p) * 15 - 0.3);
  891.  
  892.     SinPalette[0] = 0x000;
  893.     SinPalette[1] = 0xFFF;
  894.  
  895.         /* Combine all three colour ranges into a single palette. */
  896.  
  897.     for(i = 0 ; i < Wrap ; i++)
  898.     {
  899.         SinPalette[2 + i]  = Range[(RedLevel   + i) % Wrap] << 8;
  900.         SinPalette[2 + i] |= Range[(GreenLevel + i) % Wrap] << 4;
  901.         SinPalette[2 + i] |= Range[(BlueLevel  + i) % Wrap];
  902.     }
  903.  
  904.         /* Create the spectral colour table. */
  905.  
  906.     for(i = 0 ; i < 16 ; i++)
  907.         Table[c++] = (r << 8) | ((g++) << 4) | b;
  908.  
  909.     g = 15;
  910.     r--;
  911.  
  912.     for(i = 0 ; i < 15 ; i++)
  913.         Table[c++] = ((r--) << 8) | (g << 4) | b;
  914.  
  915.     r = 0;
  916.     g--;
  917.     b++;
  918.  
  919.     for(i = 0 ; i < 15 ; i++)
  920.         Table[c++] = (r << 8) | ((g--) << 4) | (b++);
  921.  
  922.     g = 0;
  923.     b = 15;
  924.     r++;
  925.  
  926.     for(i = 0 ; i < 15 ; i++)
  927.         Table[c++] = ((r++) << 8) | (g << 4) | b;
  928.  
  929.     r = 15;
  930.     b--;
  931.  
  932.     for(i = 0 ; i < 14 ; i++)
  933.         Table[c++] = (r << 8) | (g << 4) | (b--);
  934.  
  935.         /* Set up the spectral colour palette. */
  936.  
  937.     WheelPalette[0] = 0x000;
  938.     WheelPalette[1] = 0xFFF;
  939.  
  940.     for(i = 2 ; i < 32 ; i++)
  941.     {
  942.         WheelPalette[i] = Table[AltWheel];
  943.  
  944.         AltWheel = (AltWheel + 1) % 75;
  945.     }
  946.  
  947.         /* Create the colour transition table. */
  948.  
  949.     for(i = 0 ; i < 16384 ; i++)
  950.         Wave[i] = 2 + (i % ((1 << Depth) - 2));
  951.  
  952.         /* Create the main screen, first query how wide the
  953.          * current overscan settings allow a screen to be.
  954.          */
  955.  
  956.     if(!QueryOverscan(Mode,&DisplayClip,OSCAN_TEXT))
  957.         return(RETURN_FAIL + 12);
  958.  
  959.         /* Open a centered screen. */
  960.  
  961.     Differ = ((DisplayClip . MaxX - DisplayClip . MinX + 1) - Square) >> 1;
  962.  
  963.     DisplayClip . MinX += Differ;
  964.     DisplayClip . MaxX -= Differ;
  965.  
  966.         /* Allocate a couple of colour specification structures. */
  967.  
  968.     if(!(ColorSpec = (struct ColorSpec *)AllocVec(sizeof(struct ColorSpec) * ((1 << Depth) + 1),MEMF_PUBLIC|MEMF_CLEAR)))
  969.     {
  970.             /* Open a screen with monochrome system imagery. */
  971.  
  972.         if(!(Screen = OpenScreenTags(NULL,
  973.             SA_Width,    Square,
  974.             SA_Height,    Square,
  975.             SA_DClip,    &DisplayClip,
  976.             SA_Left,    DisplayClip . MinX,
  977.             SA_Depth,    Depth,
  978.             SA_DisplayID,    Mode,
  979.             SA_Font,    &DefaultFont,
  980.             SA_ShowTitle,    FALSE,
  981.             SA_Quiet,    TRUE,
  982.             SA_AutoScroll,    TRUE,
  983.             SA_Behind,    TRUE,
  984.         TAG_END)))
  985.             return(RETURN_FAIL + 13);
  986.     }
  987.     else
  988.     {
  989.             /* Set up the colour specifications to open
  990.              * an entirely black screen.
  991.              */
  992.  
  993.         for(i = 0 ; i < (1 << Depth) ; i++)
  994.             ColorSpec[i] . ColorIndex = i;
  995.  
  996.         ColorSpec[i] . ColorIndex = -1;
  997.  
  998.             /* Open a screen with monochrome system imagery. */
  999.  
  1000.         if(!(Screen = OpenScreenTags(NULL,
  1001.             SA_Width,    Square,
  1002.             SA_Height,    Square,
  1003.             SA_DClip,    &DisplayClip,
  1004.             SA_Left,    DisplayClip . MinX,
  1005.             SA_Depth,    Depth,
  1006.             SA_DisplayID,    Mode,
  1007.             SA_Font,    &DefaultFont,
  1008.             SA_ShowTitle,    FALSE,
  1009.             SA_Quiet,    TRUE,
  1010.             SA_AutoScroll,    TRUE,
  1011.             SA_Behind,    TRUE,
  1012.             SA_Colors,    ColorSpec,
  1013.         TAG_END)))
  1014.         {
  1015.             FreeVec(ColorSpec);
  1016.  
  1017.             return(RETURN_FAIL + 13);
  1018.         }
  1019.         else
  1020.             FreeVec(ColorSpec);
  1021.     }
  1022.  
  1023.         /* Set up the remaining data. */
  1024.  
  1025.     if(!(VisualInfo = GetVisualInfo(Screen,TAG_DONE)))
  1026.         return(RETURN_FAIL + 14);
  1027.  
  1028.     if(!(Menu = CreateMenus(MandelbrotMenu,
  1029.         GTMN_FrontPen, 0,
  1030.     TAG_DONE)))
  1031.         return(RETURN_FAIL + 15);
  1032.  
  1033.     if(!LayoutMenus(Menu,    VisualInfo,
  1034.         GTMN_TextAttr,    &DefaultFont,
  1035.     TAG_DONE))
  1036.         return(RETURN_FAIL + 16);
  1037.  
  1038.     if(!(Window = OpenWindowTags(NULL,
  1039.         WA_Width,    Screen -> Width,
  1040.         WA_Height,    Screen -> Height,
  1041.         WA_Borderless,    TRUE,
  1042.         WA_Backdrop,    TRUE,
  1043.         WA_IDCMP,    IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY | IDCMP_MENUVERIFY,
  1044.         WA_RMBTrap,    TRUE,
  1045.         WA_CustomScreen,Screen,
  1046.     TAG_END)))
  1047.         return(RETURN_FAIL + 17);
  1048.  
  1049.         /* Create a bitmap which is exactly as wide as the
  1050.          * main screen, but only a single line high.
  1051.          */
  1052.  
  1053.     InitBitMap(&LineBitMap,Depth,Square,1);
  1054.  
  1055.         /* Allocate space for the bitmap, note that the
  1056.          * bitplanes are to reside in fast ram.
  1057.          */
  1058.  
  1059.     if(LineBitMap . Planes[0] = AllocVec(LineBitMap . BytesPerRow * LineBitMap . Depth,MEMF_PUBLIC|MEMF_CLEAR|MEMF_FAST))
  1060.     {
  1061.         for(i = 1 ; i < LineBitMap . Depth ; i++)
  1062.             LineBitMap . Planes[i] = &LineBitMap . Planes[i - 1][LineBitMap . BytesPerRow];
  1063.     }
  1064.  
  1065.     SetMenuStrip(Window,Menu);
  1066.  
  1067.     OffMenu(Window,FULLMENUNUM(0,9,0));
  1068.  
  1069.     RPort = &Screen -> RastPort;
  1070.     VPort = &Screen -> ViewPort;
  1071.  
  1072.     SetRast(RPort,0);
  1073.  
  1074.     Window -> Flags &= ~WFLG_RMBTRAP;
  1075.  
  1076.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  1077.  
  1078.     return(0);
  1079. }
  1080.  
  1081.     /* CloseAll(LONG ReturnCode):
  1082.      *
  1083.      *    Close all remaining resources and terminate the program.
  1084.      */
  1085.  
  1086. VOID __regargs
  1087. CloseAll(LONG ReturnCode)
  1088. {
  1089.     SetTaskPri(ThisProcess,OldPri);
  1090.  
  1091.     if(GlobalBitMap)
  1092.     {
  1093.         DeleteBitMap(GlobalBitMap);
  1094.  
  1095.         GlobalBitMap = NULL;
  1096.     }
  1097.  
  1098.     StopAnim();
  1099.  
  1100.     if(CycleInterrupt)
  1101.     {
  1102.         DoCycle = FALSE;
  1103.  
  1104.         if(CycleInterrupt -> is_Code)
  1105.             RemIntServer(INTB_VERTB,CycleInterrupt);
  1106.  
  1107.         FreeVec(CycleInterrupt);
  1108.     }
  1109.  
  1110.     if(Wave)
  1111.         FreeVec(Wave);
  1112.  
  1113.     GfxCleanup();
  1114.  
  1115.     if(BackupBitMap)
  1116.         DeleteBitMap(BackupBitMap);
  1117.  
  1118.     if(TimeRequest)
  1119.     {
  1120.         if(TimeRequest -> tr_node . io_Device)
  1121.             CloseDevice(TimeRequest);
  1122.  
  1123.         DeleteIORequest(TimeRequest);
  1124.     }
  1125.  
  1126.     if(TimePort)
  1127.         DeleteMsgPort(TimePort);
  1128.  
  1129.     if(IconBase)
  1130.         CloseLibrary(IconBase);
  1131.  
  1132.     if(AslBase)
  1133.         CloseLibrary(AslBase);
  1134.  
  1135.     if(IFFParseBase)
  1136.         CloseLibrary(IFFParseBase);
  1137.  
  1138.     if(GadToolsBase)
  1139.         CloseLibrary(GadToolsBase);
  1140.  
  1141.     if(GfxBase)
  1142.         CloseLibrary(GfxBase);
  1143.  
  1144.     if(IntuitionBase)
  1145.         CloseLibrary(IntuitionBase);
  1146.  
  1147.     exit(ReturnCode);
  1148. }
  1149.  
  1150.     /* OpenAll():
  1151.      *
  1152.      *    Open libraries and other data which does not
  1153.      *    require changing when the display modes are
  1154.      *    altered.
  1155.      */
  1156.  
  1157. VOID
  1158. OpenAll()
  1159. {
  1160.     ThisProcess = (struct Process *)FindTask(NULL);
  1161.  
  1162.     OldPri = SetTaskPri(ThisProcess,0);
  1163.  
  1164.     OldPtr = ThisProcess -> pr_WindowPtr;
  1165.  
  1166.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  1167.         CloseAll(RETURN_FAIL + 0);
  1168.  
  1169.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
  1170.         CloseAll(RETURN_FAIL + 1);
  1171.  
  1172.     if(!(GadToolsBase = OpenLibrary("gadtools.library",37)))
  1173.         CloseAll(RETURN_FAIL + 2);
  1174.  
  1175.     if(!(IFFParseBase = OpenLibrary("iffparse.library",37)))
  1176.         CloseAll(RETURN_FAIL + 3);
  1177.  
  1178.     if(!(AslBase = OpenLibrary("asl.library",37)))
  1179.         CloseAll(RETURN_FAIL + 4);
  1180.  
  1181.     if(!(TimePort = (struct MsgPort *)CreateMsgPort()))
  1182.         CloseAll(RETURN_FAIL + 5);
  1183.  
  1184.     if(!(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest))))
  1185.         CloseAll(RETURN_FAIL + 6);
  1186.  
  1187.     if(OpenDevice(TIMERNAME,UNIT_VBLANK,TimeRequest,0))
  1188.         CloseAll(RETURN_FAIL + 7);
  1189.  
  1190.     if(!(BackupBitMap = CreateBitMap(5,25 * 8,8)))
  1191.         CloseAll(RETURN_FAIL + 8);
  1192.  
  1193.     if(!(CycleInterrupt = AllocVec(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR)))
  1194.         CloseAll(RETURN_FAIL + 9);
  1195.  
  1196.     if(!(Wave = (BYTE *)AllocVec(16384,MEMF_PUBLIC|MEMF_CLEAR)))
  1197.         CloseAll(RETURN_FAIL + 10);
  1198.  
  1199.     if(!(IconBase = OpenLibrary("icon.library",37)))
  1200.         CloseAll(RETURN_FAIL + 11);
  1201.  
  1202.     TimerBase = &TimeRequest -> tr_node . io_Device -> dd_Library;
  1203.  
  1204.     CycleInterrupt -> is_Node . ln_Name    = "Mandelbrot Cycling";
  1205.     CycleInterrupt -> is_Node . ln_Type    = NT_INTERRUPT;
  1206.     CycleInterrupt -> is_Code        = (APTR)CycleServer;
  1207.  
  1208.     AddIntServer(INTB_VERTB,CycleInterrupt);
  1209. }
  1210.  
  1211.     /* CopyLine(struct BitMap *BitMap,WORD Line):
  1212.      *
  1213.      *    Copies the contents of the single line bitmap to a given
  1214.      *    line on screen.
  1215.      */
  1216.  
  1217. VOID __regargs
  1218. CopyLine(struct BitMap *BitMap,WORD Line)
  1219. {
  1220.     WORD i;
  1221.  
  1222.     Line *= BitMap -> BytesPerRow;
  1223.  
  1224.     for(i = 0 ; i < BitMap -> Depth ; i++)
  1225.         CopyMemQuick(BitMap -> Planes[i],&RPort -> BitMap -> Planes[i][Line],BitMap -> BytesPerRow);
  1226. }
  1227.  
  1228.     /* GetTime():
  1229.      *
  1230.      *    Asks the timer.device for the current system time.
  1231.      */
  1232.  
  1233. VOID
  1234. GetTime()
  1235. {
  1236.     TimeRequest -> tr_node . io_Command = TR_GETSYSTIME;
  1237.  
  1238.     DoIO(TimeRequest);
  1239. }
  1240.  
  1241.     /* BlockWindow():
  1242.      *
  1243.      *    Blocks the menu bar of the window and sets the busy
  1244.      *    mouse pointer.
  1245.      */
  1246.  
  1247. VOID
  1248. BlockWindow()
  1249. {
  1250.     HoldIt = TRUE;
  1251.  
  1252.     SetWait(Window);
  1253.  
  1254.     Window -> Flags |= WFLG_RMBTRAP;
  1255. }
  1256.  
  1257.     /* ReleaseWindow():
  1258.      *
  1259.      *    Reenables the menu bar of the window and resets the
  1260.      *    mouse pointer to the default mouse pointer.
  1261.      */
  1262.  
  1263. VOID
  1264. ReleaseWindow()
  1265. {
  1266.     ClearPointer(Window);
  1267.  
  1268.     Window -> Flags &= ~WFLG_RMBTRAP;
  1269.  
  1270.     HoldIt = FALSE;
  1271. }
  1272.  
  1273.     /* GetFile():
  1274.      *
  1275.      *    Get a file name using the asl.library file requester.
  1276.      */
  1277.  
  1278. BYTE
  1279. GetFile(UBYTE *Title,UBYTE *Directory,UBYTE *Name,UBYTE *Buffer,UBYTE *Pattern,BYTE SaveFlag)
  1280. {
  1281.     struct FileRequester    *AslFileRequest;
  1282.     BYTE             Result = FALSE;
  1283.     LONG             Flags;
  1284.  
  1285.     if(!Directory[0])
  1286.         NameFromLock(ThisProcess -> pr_CurrentDir,Directory,256);
  1287.  
  1288.     if(Pattern)
  1289.     {
  1290.         Flags = FILF_PATGAD;
  1291.  
  1292.         if(!Pattern[0])
  1293.             Pattern = "~(#?.info)";
  1294.     }
  1295.     else
  1296.     {
  1297.         Flags = 0;
  1298.  
  1299.         Pattern = "~(#?.info)";
  1300.     }
  1301.  
  1302.     if(SaveFlag)
  1303.         Flags |= FILF_SAVE;
  1304.  
  1305.     if(AslFileRequest = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
  1306.         ASL_Window,    Window,
  1307.         ASL_File,    Name,
  1308.         ASL_Dir,    Directory,
  1309.         ASL_Hail,    Title,
  1310.         ASL_FuncFlags,    Flags,
  1311.         ASL_Pattern,    Pattern,
  1312.         ASL_OKText,    SaveFlag ? "Save" : "Open",
  1313.         ASL_LeftEdge,    0,
  1314.         ASL_TopEdge,    0,
  1315.         ASL_Width,    Screen -> Width,
  1316.         ASL_Height,    Screen -> Height,
  1317.     TAG_DONE))
  1318.     {
  1319.         if(RequestFile(AslFileRequest))
  1320.         {
  1321.             if(AslFileRequest -> rf_File[0])
  1322.             {
  1323.                 strcpy(Buffer,AslFileRequest -> rf_Dir);
  1324.  
  1325.                 AddPart((UBYTE *)Buffer,(UBYTE *)AslFileRequest -> rf_File,256);
  1326.  
  1327.                 Result = TRUE;
  1328.             }
  1329.         }
  1330.     }
  1331.  
  1332.     FreeFileRequest(AslFileRequest);
  1333.  
  1334.     return(Result);
  1335. }
  1336.  
  1337.     /* MyEasyRequest():
  1338.      *
  1339.      *    EasyRequestArgs stub routine.
  1340.      */
  1341.  
  1342. WORD __stdargs
  1343. MyEasyRequest(UBYTE *Gadgets,UBYTE *Text,...)
  1344. {
  1345.     struct EasyStruct    Easy;
  1346.     WORD            Result;
  1347.     ULONG            IDCMP = NULL;
  1348.     va_list             VarArgs;
  1349.  
  1350.     Easy . es_StructSize    = sizeof(struct EasyStruct);
  1351.     Easy . es_Flags        = NULL;
  1352.     Easy . es_Title        = (UBYTE *)"MandelSquare";
  1353.     Easy . es_TextFormat    = (UBYTE *)Text;
  1354.     Easy . es_GadgetFormat    = (UBYTE *)Gadgets;
  1355.  
  1356.     va_start(VarArgs,Text);
  1357.     Result = EasyRequestArgs(Window,&Easy,&IDCMP,VarArgs);
  1358.     va_end(VarArgs);
  1359.  
  1360.     return(Result);
  1361. }
  1362.  
  1363.     /* FadeTo():
  1364.      *
  1365.      *    Fades from one colour table to another.
  1366.      */
  1367.  
  1368. VOID
  1369. FadeTo(struct ViewPort *VPort,UWORD *From,UWORD *To,UBYTE NumColours,UBYTE ToCol,UBYTE FromCol)
  1370. {
  1371.     UWORD    FromTemp[32];
  1372.     UWORD    ToTemp[32];
  1373.     UBYTE    i,j;
  1374.     BYTE    R1,G1,B1,R2,G2,B2;
  1375.  
  1376.     if(NumColours > 32)
  1377.         NumColours = 32;
  1378.  
  1379.     if(From)
  1380.         CopyMem(&From[0],&FromTemp[0],sizeof(UWORD) * NumColours);
  1381.     else
  1382.         memset(&FromTemp[0],FromCol,sizeof(UWORD) * NumColours);
  1383.  
  1384.     if(To)
  1385.         CopyMem(&To[0],&ToTemp[0],sizeof(UWORD) * NumColours);
  1386.     else
  1387.         memset(&ToTemp[0],ToCol,sizeof(UWORD) * NumColours);
  1388.  
  1389.     for(j = 0 ; j < 16 ; j++)
  1390.     {
  1391.         for(i = 0 ; i < NumColours ; i++)
  1392.         {
  1393.             R1 = (FromTemp[i] >> 8)    & 0xF;
  1394.             G1 = (FromTemp[i] >> 4)    & 0xF;
  1395.             B1 = (FromTemp[i])    & 0xF;
  1396.  
  1397.             R2 = (ToTemp[i] >> 8)    & 0xF;
  1398.             G2 = (ToTemp[i] >> 4)    & 0xF;
  1399.             B2 = (ToTemp[i])    & 0xF;
  1400.  
  1401.             if(R1 > R2)
  1402.                 R1--;
  1403.  
  1404.             if(G1 > G2)
  1405.                 G1--;
  1406.  
  1407.             if(B1 > B2)
  1408.                 B1--;
  1409.  
  1410.             if(R1 < R2)
  1411.                 R1++;
  1412.  
  1413.             if(G1 < G2)
  1414.                 G1++;
  1415.  
  1416.             if(B1 < B2)
  1417.                 B1++;
  1418.  
  1419.             FromTemp[i] = (R1 << 8) | (G1 << 4) | B1;
  1420.         }
  1421.  
  1422.         Delay(2);
  1423.  
  1424.         LoadRGB4(VPort,FromTemp,NumColours);
  1425.     }
  1426. }
  1427.  
  1428.     /* Random(LONG MaxValue)
  1429.      *
  1430.      *    Small random number generator.
  1431.      */
  1432.  
  1433. ULONG __regargs
  1434. Random(LONG MaxValue)
  1435. {
  1436.     STATIC ULONG RandomSeed = 213567657;
  1437.  
  1438.     RandomSeed = RandomSeed * custom . vhposr + 8754331;
  1439.  
  1440.     return(RandomSeed % MaxValue);
  1441. }
  1442.  
  1443.     /* CreateAllCoordsGadgets():
  1444.      *
  1445.      *    Creates all gadgets required by the coordinates control panel.
  1446.      */
  1447.  
  1448. struct Gadget *
  1449. CreateAllCoordsGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1450. {
  1451.     struct Gadget        *Gadget;
  1452.     struct NewGadget     NewGadget;
  1453.     UWORD             Counter = 0;
  1454.     UBYTE             Buffer[40];
  1455.  
  1456.     if(Gadget = CreateContext(GadgetList))
  1457.     {
  1458.         NewGadget . ng_Width        = COORDS_WIDTH - 20;
  1459.         NewGadget . ng_Height        = 14;
  1460.         NewGadget . ng_GadgetText    = "Real Part (X-Coordinate)";
  1461.         NewGadget . ng_TextAttr        = &DefaultFont;
  1462.         NewGadget . ng_VisualInfo    = VisualInfo;
  1463.         NewGadget . ng_GadgetID        = Counter;
  1464.         NewGadget . ng_Flags        = PLACETEXT_ABOVE;
  1465.         NewGadget . ng_LeftEdge        = 10;
  1466.         NewGadget . ng_TopEdge        = 2 + TopEdge + 14;
  1467.  
  1468.         sprintf(Buffer,"%g",MinReal);
  1469.  
  1470.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1471.             GTST_MaxChars,        40,
  1472.             GTST_String,        Buffer,
  1473.             STRINGA_Justification,    STRINGCENTER,
  1474.         TAG_DONE);
  1475.  
  1476.         BailOut();
  1477.  
  1478.         NewGadget . ng_GadgetText    = "Imaginary Part (Y-Coordinate)";
  1479.         NewGadget . ng_GadgetID        = Counter;
  1480.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 4 + 15;
  1481.  
  1482.         sprintf(Buffer,"%g",MinImaginary);
  1483.  
  1484.         BailOut();
  1485.  
  1486.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1487.             GTST_MaxChars,        40,
  1488.             GTST_String,        Buffer,
  1489.             STRINGA_Justification,    STRINGCENTER,
  1490.         TAG_DONE);
  1491.  
  1492.         NewGadget . ng_GadgetText    = "Width & Height";
  1493.         NewGadget . ng_GadgetID        = Counter;
  1494.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 4 + 15;
  1495.  
  1496.         sprintf(Buffer,"%g",RealWidth);
  1497.  
  1498.         BailOut();
  1499.  
  1500.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  1501.             GTST_MaxChars,        40,
  1502.             GTST_String,        Buffer,
  1503.             STRINGA_Justification,    STRINGCENTER,
  1504.         TAG_DONE);
  1505.  
  1506.         NewGadget . ng_Width        = 68;
  1507.         NewGadget . ng_Height        = 12;
  1508.         NewGadget . ng_GadgetText    = "Accept";
  1509.         NewGadget . ng_GadgetID        = Counter;
  1510.         NewGadget . ng_Flags        = 0;
  1511.         NewGadget . ng_TopEdge        = COORDS_HEIGHT - 3 - NewGadget . ng_Height;
  1512.  
  1513.         BailOut();
  1514.  
  1515.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1516.             TAG_DONE);
  1517.  
  1518.         NewGadget . ng_GadgetText    = "Cancel";
  1519.         NewGadget . ng_GadgetID        = Counter;
  1520.         NewGadget . ng_LeftEdge        = COORDS_WIDTH - 10 - NewGadget . ng_Width;
  1521.  
  1522.         BailOut();
  1523.  
  1524.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1525.             TAG_DONE);
  1526.     }
  1527.  
  1528.     return(Gadget);
  1529. }
  1530.  
  1531.     /* CreateAllPaletteGadgets():
  1532.      *
  1533.      *    Creates all gadgets required by the palette control panel.
  1534.      */
  1535.  
  1536. struct Gadget *
  1537. CreateAllPaletteGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1538. {
  1539.     struct Gadget        *Gadget;
  1540.     struct NewGadget     NewGadget;
  1541.     UWORD             Counter = 0;
  1542.  
  1543.     if(Gadget = CreateContext(GadgetList))
  1544.     {
  1545.         NewGadget . ng_Width        = 60;
  1546.         NewGadget . ng_Height        = 12;
  1547.         NewGadget . ng_GadgetText    = "Red  ";
  1548.         NewGadget . ng_TextAttr        = &DefaultFont;
  1549.         NewGadget . ng_VisualInfo    = VisualInfo;
  1550.         NewGadget . ng_GadgetID        = Counter;
  1551.         NewGadget . ng_Flags        = PLACETEXT_LEFT;
  1552.         NewGadget . ng_LeftEdge        = 18 + 8 * strlen(NewGadget . ng_GadgetText);
  1553.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  1554.  
  1555.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  1556.             GTSL_Min,        0,
  1557.             GTSL_Max,        (1 << Depth) - 3,
  1558.             GTSL_Level,        RedLevel,
  1559.         TAG_DONE);
  1560.  
  1561.         NewGadget . ng_GadgetText    = "Green";
  1562.         NewGadget . ng_GadgetID        = Counter;
  1563.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 3;
  1564.  
  1565.         BailOut();
  1566.  
  1567.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  1568.             GTSL_Min,        0,
  1569.             GTSL_Max,        (1 << Depth) - 3,
  1570.             GTSL_Level,        GreenLevel,
  1571.         TAG_DONE);
  1572.  
  1573.         NewGadget . ng_GadgetText    = "Blue ";
  1574.         NewGadget . ng_GadgetID        = Counter;
  1575.         NewGadget . ng_TopEdge        = Gadget -> TopEdge + Gadget -> Height + 3;
  1576.  
  1577.         BailOut();
  1578.  
  1579.         GadgetArray[Counter++] = Gadget = CreateGadget(SLIDER_KIND,Gadget,&NewGadget,
  1580.             GTSL_Min,        0,
  1581.             GTSL_Max,        (1 << Depth) - 3,
  1582.             GTSL_Level,        BlueLevel,
  1583.         TAG_DONE);
  1584.     }
  1585.  
  1586.     return(Gadget);
  1587. }
  1588.  
  1589.     /* CreateAllScrollGadgets():
  1590.      *
  1591.      *    Creates all the gadgets required by the scroll amount
  1592.      *    control panel.
  1593.      */
  1594.  
  1595. struct Gadget *
  1596. CreateAllScrollGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  1597. {
  1598.     struct Gadget        *Gadget;
  1599.     struct NewGadget     NewGadget;
  1600.     UWORD             Counter = 0;
  1601.  
  1602.     if(Gadget = CreateContext(GadgetList))
  1603.     {
  1604.         NewGadget . ng_Width        = 44;
  1605.         NewGadget . ng_Height        = 14;
  1606.         NewGadget . ng_GadgetText    = "Scroll Amount";
  1607.         NewGadget . ng_TextAttr        = &DefaultFont;
  1608.         NewGadget . ng_VisualInfo    = VisualInfo;
  1609.         NewGadget . ng_GadgetID        = Counter;
  1610.         NewGadget . ng_Flags        = 0;
  1611.         NewGadget . ng_LeftEdge        = (strlen(NewGadget . ng_GadgetText) + 2) * 8 + 1;
  1612.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  1613.  
  1614.         GadgetArray[Counter++] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,
  1615.             GTIN_MaxChars,    3,
  1616.             GTIN_Number,    (LONG)MaxScroll,
  1617.         TAG_DONE);
  1618.  
  1619.         NewGadget . ng_Width        = 52;
  1620.         NewGadget . ng_Height        = 12;
  1621.         NewGadget . ng_GadgetText    = "Accept";
  1622.         NewGadget . ng_GadgetID        = Counter;
  1623.         NewGadget . ng_Flags        = 0;
  1624.         NewGadget . ng_LeftEdge        = 10;
  1625.         NewGadget . ng_TopEdge        = SCROLL_HEIGHT - 3 - NewGadget . ng_Height;
  1626.  
  1627.         BailOut();
  1628.  
  1629.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1630.             TAG_DONE);
  1631.  
  1632.         NewGadget . ng_GadgetText    = "Cancel";
  1633.         NewGadget . ng_GadgetID        = Counter;
  1634.         NewGadget . ng_LeftEdge        = SCROLL_WIDTH - 10 - NewGadget . ng_Width;
  1635.  
  1636.         BailOut();
  1637.  
  1638.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,
  1639.             TAG_DONE);
  1640.     }
  1641.  
  1642.     return(Gadget);
  1643. }
  1644.  
  1645.     /* InfoText():
  1646.      *
  1647.      *    Renders a small position and size information text into
  1648.      *    the left bottom corner of the screen.
  1649.      */
  1650.  
  1651. VOID
  1652. InfoText()
  1653. {
  1654.     struct TextFont    *OldFont;
  1655.     UBYTE         Buffer[80];
  1656.     WORD         i;
  1657.     struct RastPort    *RPort = Window -> RPort;
  1658.  
  1659.     BlockWindow();
  1660.  
  1661.     OldFont = RPort -> Font;
  1662.  
  1663.     SetFont(RPort,&DigitFont);
  1664.     SetAPen(RPort,1);
  1665.  
  1666.     sprintf(Buffer,"(/%1.04e )/%1.04e %1.04e*%1.04e",MinReal,MinImaginary,RealWidth,ImaginaryHeight);
  1667.  
  1668.     for(i = 0 ; i < strlen(Buffer) ; i++)
  1669.     {
  1670.         if(Buffer[i] == 'e')
  1671.             Buffer[i] = '$';
  1672.     }
  1673.  
  1674.     SetDrMd(RPort,JAM1);
  1675.  
  1676.     Move(RPort,1,Window -> Height - 2);
  1677.     Text(RPort,Buffer,strlen(Buffer));
  1678.  
  1679.     SetFont(RPort,OldFont);
  1680.     SetDrMd(RPort,JAM2);
  1681. }
  1682.  
  1683.     /* CalculateFrames():
  1684.      *
  1685.      *    Precalculates the number of pictures to be generated
  1686.      *    when zooming to a specific location in the Mandelbrot
  1687.      *    set.
  1688.      */
  1689.  
  1690. WORD
  1691. CalculateFrames(double MinReal,double MinImaginary,double Size)
  1692. {
  1693.     double    Data[3],Div,Value,FourPixels,GlobalSize,GlobalMinReal,GlobalMinImaginary;
  1694.     BYTE    i,Render;
  1695.     WORD    Count = 0;
  1696.  
  1697.     GlobalSize        = LastSize;
  1698.     GlobalMinReal        = LastMinReal;
  1699.     GlobalMinImaginary    = LastMinImaginary;
  1700.  
  1701.     do
  1702.     {
  1703.         Data[0]    = GlobalSize - Size;
  1704.         Data[1]    = MinReal - GlobalMinReal;
  1705.         Data[2] = MinImaginary - GlobalMinImaginary;
  1706.  
  1707.         Value    = fabs(Data[0]);
  1708.         Render    = FALSE;
  1709.  
  1710.         for(i = 0 ; i < 3 ; i++)
  1711.         {
  1712.             if(Data[i] != 0.0)
  1713.                 Render = TRUE;
  1714.  
  1715.             if(fabs(Data[i]) > Value)
  1716.                 Value = fabs(Data[i]);
  1717.         }
  1718.  
  1719.         if(Render)
  1720.         {
  1721.             FourPixels    = MaxScroll * (GlobalSize / (double)Screen -> Width);
  1722.             Div        = Value;
  1723.  
  1724.             if(Value > FourPixels)
  1725.                 Value = FourPixels;
  1726.  
  1727.             Div /= Value;
  1728.  
  1729.             GlobalSize        -= Data[0] / Div;
  1730.             GlobalMinReal        += Data[1] / Div;
  1731.             GlobalMinImaginary    += Data[2] / Div;
  1732.  
  1733.             Count++;
  1734.         }
  1735.     }
  1736.     while(Render);
  1737.  
  1738.     return(Count);
  1739. }
  1740.  
  1741.     /* CheckAbort():
  1742.      *
  1743.      *    Provides a safe callback routine to allow the anim
  1744.      *    player to check for a user abort.
  1745.      */
  1746.  
  1747. BYTE
  1748. CheckAbort()
  1749. {
  1750.     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  1751.     {
  1752.         struct IntuiMessage    *Massage;
  1753.         ULONG             Class,Code;
  1754.  
  1755.         while(Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort))
  1756.         {
  1757.             Class    = Massage -> Class;
  1758.             Code    = Massage -> Code;
  1759.  
  1760.             GT_ReplyIMsg(Massage);
  1761.  
  1762.             if((Class == IDCMP_MOUSEBUTTONS && !(Code & IECODE_UP_PREFIX)) || Class == IDCMP_VANILLAKEY)
  1763.                 return(TRUE);
  1764.         }
  1765.     }
  1766.     else
  1767.         return(FALSE);
  1768. }
  1769.  
  1770.     /* ReplayAnim():
  1771.      *
  1772.      *    Loads and replays an animation file.
  1773.      */
  1774.  
  1775. BYTE
  1776. ReplayAnim()
  1777. {
  1778.     BYTE     Success = FALSE;
  1779.     UBYTE    *DummyChar;
  1780.  
  1781.     strcpy(DummyBuffer,AnimPlayName);
  1782.  
  1783.     DummyChar = PathPart(DummyBuffer);
  1784.  
  1785.     *DummyChar = 0;
  1786.  
  1787.     if(GetFile("Replay Animation",DummyBuffer,FilePart(AnimPlayName),DummyBuffer,"~(#?.info)",FALSE))
  1788.     {
  1789.         BPTR File;
  1790.  
  1791.         if(File = Open(DummyBuffer,MODE_OLDFILE))
  1792.         {
  1793.             if(CreateBuffer())
  1794.             {
  1795.                 if(OpenPreLoadIFF(File))
  1796.                 {
  1797.                     strcpy(AnimPlayName,DummyBuffer);
  1798.  
  1799.                     SetClear(Window);
  1800.  
  1801.                     SwapBits();
  1802.  
  1803.                     Success = TRUE;
  1804.  
  1805.                     while(PlayAnim());
  1806.  
  1807.                     ClosePreLoadIFF();
  1808.                 }
  1809.                 else
  1810.                     MyEasyRequest("Continue","Could not read file\n%s.",FilePart(DummyBuffer));
  1811.  
  1812.                 SetWait(Window);
  1813.  
  1814.                 DeleteBuffer();
  1815.             }
  1816.             else
  1817.                 MyEasyRequest("Continue","Not enough memory for\ndisplay buffer.");
  1818.  
  1819.             Close(File);
  1820.         }
  1821.         else
  1822.             MyEasyRequest("Continue","Error opening file\n%s.",FilePart(DummyBuffer));
  1823.     }
  1824.  
  1825.     return(Success);
  1826. }
  1827.  
  1828.     /* RunAnim():
  1829.      *
  1830.      *    This routine calculates the single animation frames and
  1831.      *    stores them in the anim file.
  1832.      */
  1833.  
  1834. VOID
  1835. RunAnim()
  1836. {
  1837.     double    Data[3],Value,Div,SomePixels;
  1838.     BYTE    Render,i;
  1839.  
  1840.     LastSize        = RealWidth;
  1841.     LastMinReal        = MinReal;
  1842.     LastMinImaginary    = MinImaginary;
  1843.  
  1844.     NewCoords = FALSE;
  1845.  
  1846.     while(AnimRunning && !NewCoords)
  1847.         Zoom();
  1848.  
  1849. /*    Coords();*/
  1850.  
  1851.     if(NewCoords)
  1852.     {
  1853.         if(!AnimOpened)
  1854.         {
  1855.             UBYTE *DummyChar;
  1856.  
  1857.             AnimRunning = FALSE;
  1858.  
  1859.             strcpy(DummyBuffer,AnimSaveName);
  1860.  
  1861.             DummyChar = PathPart(DummyBuffer);
  1862.  
  1863.             *DummyChar = 0;
  1864.  
  1865.             if(GetFile("Begin Animation",DummyBuffer,FilePart(AnimSaveName),DummyBuffer,"~(#?.info)",FALSE))
  1866.             {
  1867.                 if(Frame)
  1868.                 {
  1869.                     WORD    X,Y,Width;
  1870.                     double    Pixel;
  1871.  
  1872.                     Pixel    = LastSize / (double)Screen -> Width;
  1873.  
  1874.                     X    = (WORD)(fabs(LastMinReal - MainMinReal) / Pixel);
  1875.                     Y    = (WORD)(fabs(LastMinImaginary - MainMinImaginary) / Pixel);
  1876.                     Width    = (WORD)(MainRealWidth / Pixel);
  1877.  
  1878.                     if(X || Y || Width != Screen -> Width)
  1879.                     {
  1880.                         SetAPen(Window -> RPort,1);
  1881.                         DrawSquare(Window -> RPort,X,Y,Width);
  1882.                     }
  1883.                 }
  1884.  
  1885.                 if(Include)
  1886.                     InfoText();
  1887.  
  1888.                 if(AnimOpened = AnimOpen(DummyBuffer,VPort,RPort))
  1889.                 {
  1890.                     if(!ThisProcess -> pr_CLI)
  1891.                         PutDiskObject(DummyBuffer,&AnimIcon);
  1892.  
  1893.                     OffMenu(Window,FULLMENUNUM(0, 0,0));
  1894.                     OffMenu(Window,FULLMENUNUM(0, 1,0));
  1895.                     OffMenu(Window,FULLMENUNUM(0, 2,0));
  1896.                     OffMenu(Window,FULLMENUNUM(0, 8,0));
  1897.                     OnMenu (Window,FULLMENUNUM(0, 9,0));
  1898.                     OffMenu(Window,FULLMENUNUM(0,11,0));
  1899.                     OffMenu(Window,FULLMENUNUM(0,12,0));
  1900.                     OffMenu(Window,FULLMENUNUM(0,14,0));
  1901.  
  1902.                     OffMenu(Window,FULLMENUNUM(1, 0,0));
  1903.                     OffMenu(Window,FULLMENUNUM(1, 1,0));
  1904.                     OffMenu(Window,FULLMENUNUM(1, 2,0));
  1905.                     OffMenu(Window,FULLMENUNUM(1, 5,0));
  1906.                     OffMenu(Window,FULLMENUNUM(1, 7,0));
  1907.                     OffMenu(Window,FULLMENUNUM(1, 8,0));
  1908.                     OffMenu(Window,FULLMENUNUM(1,10,0));
  1909.  
  1910.                     AnimRunning = TRUE;
  1911.  
  1912.                     strcpy(AnimSaveName,DummyBuffer);
  1913.                 }
  1914.             }
  1915.         }
  1916.  
  1917.         if(AnimRunning)
  1918.         {
  1919.             RealWidth        = LastSize;
  1920.             ImaginaryHeight        = LastSize;
  1921.  
  1922.             MinReal            = LastMinReal;
  1923.             MinImaginary        = LastMinImaginary;
  1924.  
  1925.             LastSize        = MainRealWidth;
  1926.             LastMinReal        = MainMinReal;
  1927.             LastMinImaginary    = MainMinImaginary;
  1928.  
  1929.             do
  1930.             {
  1931.                 Data[0]    = RealWidth - LastSize;
  1932.                 Data[1]    = LastMinReal - MinReal;
  1933.                 Data[2] = LastMinImaginary - MinImaginary;
  1934.  
  1935.                 Value    = fabs(Data[0]);
  1936.                 Render    = FALSE;
  1937.  
  1938.                 for(i = 0 ; i < 3 ; i++)
  1939.                 {
  1940.                     if(Data[i] != 0.0)
  1941.                         Render = TRUE;
  1942.  
  1943.                     if(fabs(Data[i]) > Value)
  1944.                         Value = fabs(Data[i]);
  1945.                 }
  1946.  
  1947.                 if(Render)
  1948.                 {
  1949.                     SomePixels    = MaxScroll * (RealWidth / (double)Screen -> Width);
  1950.                     Div        = Value;
  1951.  
  1952.                     if(Value > SomePixels)
  1953.                         Value = SomePixels;
  1954.  
  1955.                     Div /= Value;
  1956.  
  1957.                     RealWidth    -= Data[0] / Div;
  1958.                     ImaginaryHeight    -= Data[0] / Div;
  1959.                     MinReal        += Data[1] / Div;
  1960.                     MinImaginary    += Data[2] / Div;
  1961.  
  1962.                     RealStep    = RealWidth / (double)Window -> Width;
  1963.                     ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  1964.  
  1965.                     AreaActive    = FALSE;
  1966.                     Running        = TRUE;
  1967.  
  1968.                     FullPicture    = TRUE;
  1969.  
  1970.                     SetRast(Window -> RPort,0);
  1971.  
  1972.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,0,Window -> Width >> 1,Window -> Height >> 1);
  1973.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,0,Window -> Width >> 1,Window -> Height >> 1);
  1974.  
  1975.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  1976.                     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  1977.  
  1978.                     if(FullPicture)
  1979.                     {
  1980.                         BlockWindow();
  1981.  
  1982.                         if(Frame)
  1983.                         {
  1984.                             WORD    X,Y,Width;
  1985.                             double    Pixel;
  1986.  
  1987.                             Pixel    = RealWidth / (double)Screen -> Width;
  1988.  
  1989.                             X    = (WORD)(fabs(MinReal - LastMinReal) / Pixel);
  1990.                             Y    = (WORD)(fabs(MinImaginary - LastMinImaginary) / Pixel);
  1991.                             Width    = (WORD)(LastSize / Pixel);
  1992.  
  1993.                             if(X || Y || Width != Screen -> Width)
  1994.                             {
  1995.                                 SetAPen(Window -> RPort,1);
  1996.                                 DrawSquare(Window -> RPort,X,Y,Width);
  1997.                             }
  1998.                         }
  1999.  
  2000.                         if(Include)
  2001.                             InfoText();
  2002.  
  2003.                         AnimAdd(RPort);
  2004.  
  2005.                         ReleaseWindow();
  2006.                     }
  2007.  
  2008.                     if(!AnimRunning)
  2009.                         break;
  2010.                 }
  2011.             }
  2012.             while(Render);
  2013.  
  2014.             if(!Render)
  2015.             {
  2016.                 MoveScreen(Screen,0,-Screen -> TopEdge);
  2017.  
  2018.                 ScreenToFront(Screen);
  2019.  
  2020.                 ActivateWindow(Window);
  2021.  
  2022.                 Delay(10);
  2023.  
  2024.                 DisplayBeep(Screen);
  2025.             }
  2026.         }
  2027.  
  2028.         AreaActive    = FALSE;
  2029.         Running        = FALSE;
  2030.     }
  2031.     else
  2032.         StopAnim();
  2033. }
  2034.  
  2035.     /* StopAnim():
  2036.      *
  2037.      *    Stops the animation generation.
  2038.      */
  2039.  
  2040. VOID
  2041. StopAnim()
  2042. {
  2043.     if(AnimRunning)
  2044.     {
  2045.         AnimRunning = FALSE;
  2046.  
  2047.         OnMenu (Window,FULLMENUNUM(0, 0,0));
  2048.         OnMenu (Window,FULLMENUNUM(0, 1,0));
  2049.         OnMenu (Window,FULLMENUNUM(0, 2,0));
  2050.         OnMenu (Window,FULLMENUNUM(0, 8,0));
  2051.         OffMenu(Window,FULLMENUNUM(0, 9,0));
  2052.         OnMenu (Window,FULLMENUNUM(0,11,0));
  2053.         OnMenu (Window,FULLMENUNUM(0,12,0));
  2054.         OnMenu (Window,FULLMENUNUM(0,14,0));
  2055.  
  2056.         OnMenu (Window,FULLMENUNUM(1, 0,0));
  2057.         OnMenu (Window,FULLMENUNUM(1, 1,0));
  2058.         OnMenu (Window,FULLMENUNUM(1, 2,0));
  2059.         OnMenu (Window,FULLMENUNUM(1, 5,0));
  2060.         OnMenu (Window,FULLMENUNUM(1, 7,0));
  2061.         OnMenu (Window,FULLMENUNUM(1, 8,0));
  2062.         OnMenu (Window,FULLMENUNUM(1,10,0));
  2063.  
  2064.         AnimClose();
  2065.  
  2066.         AnimOpened = FALSE;
  2067.     }
  2068. }
  2069.  
  2070.     /* Coords():
  2071.      *
  2072.      *    This routine implements the coordinates control panel.
  2073.      */
  2074.  
  2075. VOID
  2076. Coords()
  2077. {
  2078.     struct Gadget    *GadgetList = NULL;
  2079.     struct Gadget    *GadgetArray[5];
  2080.     struct Window    *CoordsWindow;
  2081.  
  2082.     double         TempMinReal,TempMinImaginary,
  2083.              TempRealWidth,TempImaginaryHeight;
  2084.  
  2085.     BYTE         MadeChanges = FALSE;
  2086.  
  2087.     TempMinReal        = MinReal;
  2088.     TempMinImaginary    = MinImaginary;
  2089.     TempRealWidth        = RealWidth;
  2090.     TempImaginaryHeight    = ImaginaryHeight;
  2091.  
  2092.     if(CreateAllCoordsGadgets(&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  2093.     {
  2094.         if(CoordsWindow = OpenWindowTags(NULL,
  2095.             WA_Width,    COORDS_WIDTH,
  2096.             WA_Height,    COORDS_HEIGHT,
  2097.             WA_Top,        (Screen -> Height - COORDS_HEIGHT) >> 1,
  2098.             WA_Left,    (Screen -> Width - COORDS_WIDTH) >> 1,
  2099.             WA_Activate,    TRUE,
  2100.             WA_DragBar,    FALSE,
  2101.             WA_CloseGadget,    TRUE,
  2102.             WA_RMBTrap,    TRUE,
  2103.             WA_IDCMP,    IDCMP_CLOSEWINDOW | BUTTONIDCMP | STRINGIDCMP,
  2104.             WA_Title,    "Coordinates",
  2105.             WA_CustomScreen,Screen,
  2106.         TAG_DONE))
  2107.         {
  2108.             struct IntuiMessage    *Massage;
  2109.             ULONG             Class;
  2110.             struct Gadget        *Gadget;
  2111.             BYTE             Terminated = FALSE;
  2112.  
  2113.             AddGList(CoordsWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2114.             RefreshGList(GadgetList,CoordsWindow,NULL,(UWORD)-1);
  2115.             GT_RefreshWindow(CoordsWindow,NULL);
  2116.  
  2117.             ActivateGadget(GadgetArray[0],CoordsWindow,NULL);
  2118.  
  2119.             while(!Terminated)
  2120.             {
  2121.                 WaitPort(CoordsWindow -> UserPort);
  2122.  
  2123.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(CoordsWindow -> UserPort)))
  2124.                 {
  2125.                     Class    = Massage -> Class;
  2126.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2127.  
  2128.                     GT_ReplyIMsg(Massage);
  2129.  
  2130.                     if(Class == IDCMP_CLOSEWINDOW)
  2131.                         Terminated = TRUE;
  2132.  
  2133.                     if(Class == IDCMP_GADGETUP)
  2134.                     {
  2135.                         double Value;
  2136.  
  2137.                         switch(Gadget -> GadgetID)
  2138.                         {
  2139.                             case 3:    if(MadeChanges)
  2140.                                 {
  2141.                                     MinReal        = TempMinReal;
  2142.                                     MinImaginary    = TempMinImaginary;
  2143.                                     RealWidth    = TempRealWidth;
  2144.                                     ImaginaryHeight    = TempImaginaryHeight;
  2145.  
  2146.                                     RealStep    = RealWidth / (double)Window -> Width;
  2147.                                     ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  2148.  
  2149.                                     MainMinReal        = MinReal;
  2150.                                     MainMinImaginary    = MinImaginary;
  2151.                                     MainRealWidth        = RealWidth;
  2152.                                     MainImaginaryHeight    = ImaginaryHeight;
  2153.  
  2154.                                     NewCoords    = TRUE;
  2155.                                     Running        = FALSE;
  2156.                                     AreaActive    = FALSE;
  2157.                                 }
  2158.  
  2159.                                 Terminated = TRUE;
  2160.                                 break;
  2161.  
  2162.                             case 4:    Terminated = TRUE;
  2163.                                 break;
  2164.  
  2165.                             default:Value = atof(((struct StringInfo *)Gadget -> SpecialInfo) -> Buffer);
  2166.  
  2167.                                 MadeChanges = TRUE;
  2168.  
  2169.                                 switch(Gadget -> GadgetID)
  2170.                                 {
  2171.                                     case 0:    TempMinReal        = Value;
  2172.                                         break;
  2173.  
  2174.                                     case 1:    TempMinImaginary    = Value;
  2175.                                         break;
  2176.  
  2177.                                     case 2:    TempRealWidth        = Value;
  2178.                                         TempImaginaryHeight    = Value;
  2179.                                         break;
  2180.                                 }
  2181.  
  2182.                                 break;
  2183.                         }
  2184.                     }
  2185.                 }
  2186.             }
  2187.  
  2188.             CloseWindow(CoordsWindow);
  2189.         }
  2190.     }
  2191.  
  2192.     FreeGadgets(GadgetList);
  2193. }
  2194.  
  2195.     /* Palette():
  2196.      *
  2197.      *    This routine implements the palette control panel.
  2198.      */
  2199.  
  2200. VOID
  2201. Palette()
  2202. {
  2203.     struct Gadget    *GadgetList = NULL;
  2204.     struct Gadget    *GadgetArray[3];
  2205.     struct Window    *Window;
  2206.  
  2207.     if(CreateAllPaletteGadgets(&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  2208.     {
  2209.         if(Window = OpenWindowTags(NULL,
  2210.             WA_Width,    PALETTE_WIDTH,
  2211.             WA_Height,    PALETTE_HEIGHT,
  2212.  
  2213.             WA_Top,        (Screen -> Height - PALETTE_HEIGHT) >> 1,
  2214.             WA_Left,    (Screen -> Width - PALETTE_WIDTH) >> 1,
  2215.  
  2216.             WA_Activate,    TRUE,
  2217.             WA_DragBar,    TRUE,
  2218.             WA_CloseGadget, TRUE,
  2219.             WA_RMBTrap,    TRUE,
  2220.  
  2221.             WA_IDCMP,    IDCMP_CLOSEWINDOW | SLIDERIDCMP,
  2222.             WA_CustomScreen,Screen,
  2223.  
  2224.             WA_Title,    "Palette",
  2225.         TAG_DONE))
  2226.         {
  2227.             struct IntuiMessage    *Massage;
  2228.             ULONG             Class,Code;
  2229.             struct Gadget        *Gadget;
  2230.             BYTE             Terminated = FALSE;
  2231.             WORD             i,Width = 120 / ((1 << Depth) - 2),Top = Screen -> WBorTop + Screen -> Font -> ta_YSize + 2;
  2232.  
  2233.             AddGList(Window,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2234.             RefreshGList(GadgetList,Window,NULL,(UWORD)-1);
  2235.             GT_RefreshWindow(Window,NULL);
  2236.  
  2237.             for(i = 2 ; i < (1 << Depth) ; i++)
  2238.             {
  2239.                 SetAPen(Window -> RPort,i);
  2240.  
  2241.                 RectFill(Window -> RPort,111 + 8 + (i - 2) * Width,Top,111 + 8 + (i - 1) * Width - 1,Window -> Height - Window -> BorderBottom - 2);
  2242.             }
  2243.  
  2244.             if(DoCycle)
  2245.             {
  2246.                 DoCycle = FALSE;
  2247.  
  2248.                 GetScreenPalette();
  2249.  
  2250.                 FadeTo(&Screen -> ViewPort,ScreenPalette,SinPalette,1 << Depth,0,0);
  2251.             }
  2252.             else
  2253.                 DoCycle = FALSE;
  2254.  
  2255.             UseWheel = FALSE;
  2256.  
  2257.             while(!Terminated)
  2258.             {
  2259.                 WaitPort(Window -> UserPort);
  2260.  
  2261.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(Window -> UserPort)))
  2262.                 {
  2263.                     Class    = Massage -> Class;
  2264.                     Code    = Massage -> Code;
  2265.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2266.  
  2267.                     GT_ReplyIMsg(Massage);
  2268.  
  2269.                     if(Class == IDCMP_CLOSEWINDOW)
  2270.                         Terminated = TRUE;
  2271.  
  2272.                     if(Class == IDCMP_MOUSEMOVE)
  2273.                     {
  2274.                         WORD Wrap = (1 << Depth) - 2;
  2275.  
  2276.                         switch(Gadget -> GadgetID)
  2277.                         {
  2278.                             case 0:    RedLevel = Code;
  2279.                                 break;
  2280.  
  2281.                             case 1:    GreenLevel = Code;
  2282.                                 break;
  2283.  
  2284.                             case 2:    BlueLevel = Code;
  2285.                                 break;
  2286.                         }
  2287.  
  2288.                         SinPalette[0] = 0x000;
  2289.                         SinPalette[1] = 0xFFF;
  2290.  
  2291.                         for(i = 0 ; i < Wrap ; i++)
  2292.                         {
  2293.                             SinPalette[2 + i]  = Range[(RedLevel + i) % Wrap] << 8;
  2294.                             SinPalette[2 + i] |= Range[(GreenLevel + i) % Wrap] << 4;
  2295.                             SinPalette[2 + i] |= Range[(BlueLevel + i) % Wrap];
  2296.                         }
  2297.  
  2298.                         LoadRGB4(&Screen -> ViewPort,SinPalette,1 << Depth);
  2299.                     }
  2300.                 }
  2301.             }
  2302.  
  2303.             CloseWindow(Window);
  2304.         }
  2305.     }
  2306.  
  2307.     FreeGadgets(GadgetList);
  2308. }
  2309.  
  2310.     /* MaxScrollPanel():
  2311.      *
  2312.      *    This routine implements the scroll amount control panel.
  2313.      */
  2314.  
  2315. VOID
  2316. MaxScrollPanel()
  2317. {
  2318.     struct Gadget    *GadgetList = NULL;
  2319.     struct Gadget    *GadgetArray[3];
  2320.     struct Window    *ScrollWindow;
  2321.  
  2322.     if(CreateAllScrollGadgets(&GadgetArray[0],&GadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  2323.     {
  2324.         if(ScrollWindow = OpenWindowTags(NULL,
  2325.             WA_Width,    SCROLL_WIDTH,
  2326.             WA_Height,    SCROLL_HEIGHT,
  2327.  
  2328.             WA_Top,        (Screen -> Height - SCROLL_HEIGHT) >> 1,
  2329.             WA_Left,    (Screen -> Width - SCROLL_WIDTH) >> 1,
  2330.  
  2331.             WA_Activate,    TRUE,
  2332.             WA_DragBar,    TRUE,
  2333.             WA_DepthGadget,    TRUE,
  2334.             WA_CloseGadget,    TRUE,
  2335.             WA_RMBTrap,    TRUE,
  2336.             WA_CustomScreen,Screen,
  2337.  
  2338.             WA_IDCMP,    IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | BUTTONIDCMP | INTEGERIDCMP,
  2339.  
  2340.             WA_Title,    "Set Scroll Amount",
  2341.         TAG_DONE))
  2342.         {
  2343.             struct IntuiMessage    *Massage;
  2344.             ULONG             Class;
  2345.             struct Gadget        *Gadget;
  2346.             BYTE             Terminated = FALSE;
  2347.  
  2348.             AddGList(ScrollWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  2349.             RefreshGList(GadgetList,ScrollWindow,NULL,(UWORD)-1);
  2350.             GT_RefreshWindow(ScrollWindow,NULL);
  2351.  
  2352.             ActivateGadget(GadgetArray[0],ScrollWindow,NULL);
  2353.  
  2354.             while(!Terminated)
  2355.             {
  2356.                 WaitPort(ScrollWindow -> UserPort);
  2357.  
  2358.                 while(!Terminated && (Massage = (struct IntuiMessage *)GT_GetIMsg(ScrollWindow -> UserPort)))
  2359.                 {
  2360.                     Class    = Massage -> Class;
  2361.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  2362.  
  2363.                     GT_ReplyIMsg(Massage);
  2364.  
  2365.                     if(Class == IDCMP_CLOSEWINDOW)
  2366.                         Terminated = TRUE;
  2367.  
  2368.                     if(Class == IDCMP_ACTIVEWINDOW)
  2369.                         ActivateGadget(GadgetArray[0],ScrollWindow,NULL);
  2370.  
  2371.                     if(Class == IDCMP_GADGETUP)
  2372.                     {
  2373.                         if(Gadget -> GadgetID == 2)
  2374.                             Terminated = TRUE;
  2375.                         else
  2376.                         {
  2377.                             LONG Value = ((struct StringInfo *)GadgetArray[0] -> SpecialInfo) -> LongInt;
  2378.                             BYTE GoodValue = TRUE;
  2379.  
  2380.                             if(Value < 1)
  2381.                             {
  2382.                                 GoodValue    = FALSE;
  2383.                                 Value        = 1;
  2384.                             }
  2385.  
  2386.                             if(Value >= Screen -> Width)
  2387.                             {
  2388.                                 GoodValue    = FALSE;
  2389.                                 Value        = Screen -> Width - 1;
  2390.                             }
  2391.  
  2392.                             if(GoodValue)
  2393.                             {
  2394.                                 MaxScroll    = (double)Value;
  2395.                                 Terminated    = TRUE;
  2396.                             }
  2397.                             else
  2398.                             {
  2399.                                 GT_SetGadgetAttrs(GadgetArray[0],ScrollWindow,NULL,
  2400.                                     GTIN_Number,Value,
  2401.                                 TAG_DONE);
  2402.  
  2403.                                 DisplayBeep(Screen);
  2404.  
  2405.                                 ActivateGadget(GadgetArray[0],ScrollWindow,NULL);
  2406.                             }
  2407.                         }
  2408.                     }
  2409.                 }
  2410.             }
  2411.  
  2412.             CloseWindow(ScrollWindow);
  2413.         }
  2414.     }
  2415.  
  2416.     FreeGadgets(GadgetList);
  2417. }
  2418.  
  2419.     /* AreaZoom():
  2420.      *
  2421.      *    This routine handles the selection of an area on screen
  2422.      *    to recalculate later.
  2423.      */
  2424.  
  2425. VOID
  2426. AreaZoom()
  2427. {
  2428.     struct IntuiMessage    *Massage;
  2429.     ULONG             Class,Code;
  2430.     UWORD             X,Y,LastX,LastY;
  2431.  
  2432.     SetClear(Window);
  2433.  
  2434.     Code = NULL;
  2435.  
  2436.     Window -> Flags |= WFLG_RMBTRAP;
  2437.  
  2438.     ReportMouse(TRUE,Window);
  2439.  
  2440.     SetAPen(RPort,1);
  2441.     SetDrMd(RPort,COMPLEMENT);
  2442.  
  2443.     LastX    = Window -> MouseX;
  2444.     LastY    = Window -> MouseY;
  2445.  
  2446.     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2447.     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2448.  
  2449.     while(Code != SELECTUP)
  2450.     {
  2451.         WaitPort(Window -> UserPort);
  2452.  
  2453.         if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2454.         {
  2455.             Class    = Massage -> Class;
  2456.             Code    = Massage -> Code;
  2457.  
  2458.             X    = Massage -> MouseX;
  2459.             Y    = Massage -> MouseY;
  2460.  
  2461.             ReplyMsg(&Massage -> ExecMessage);
  2462.  
  2463.             if(Class == IDCMP_MOUSEMOVE)
  2464.             {
  2465.                 if(LastX != X)
  2466.                 {
  2467.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2468.                     DrawLine(RPort,X,0,X,Screen -> Height - 1);
  2469.                 }
  2470.  
  2471.                 if(LastY != Y)
  2472.                 {
  2473.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2474.                     DrawLine(RPort,0,Y,Screen -> Width - 1,Y);
  2475.                 }
  2476.  
  2477.                 LastX = X;
  2478.                 LastY = Y;
  2479.             }
  2480.  
  2481.             if(Class == IDCMP_MOUSEBUTTONS)
  2482.             {
  2483.                 if(Code == SELECTDOWN)
  2484.                 {
  2485.                     UWORD    Left,Top,Width = 0,Height = 0;
  2486.                     BYTE    DidBox = FALSE;
  2487.  
  2488.                     Left    = X;
  2489.                     Top    = Y;
  2490.  
  2491.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2492.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2493.  
  2494.                     while(Code != SELECTUP)
  2495.                     {
  2496.                         WaitPort(Window -> UserPort);
  2497.  
  2498.                         while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2499.                         {
  2500.                             Class    = Massage -> Class;
  2501.                             Code    = Massage -> Code;
  2502.  
  2503.                             Y    = Massage -> MouseY;
  2504.                             X    = Massage -> MouseX;
  2505.  
  2506.                             ReplyMsg(&Massage -> ExecMessage);
  2507.  
  2508.                             if(Class == IDCMP_MOUSEMOVE)
  2509.                             {
  2510.                                 if(Y > Top && X > Left)
  2511.                                 {
  2512.                                     if(DidBox)
  2513.                                     {
  2514.                                         Move(RPort,Left,Top);
  2515.                                         Draw(RPort,Left + Width - 1,Top);
  2516.                                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2517.                                         Draw(RPort,Left,Top + Height - 1);
  2518.                                         Draw(RPort,Left,Top + 1);
  2519.                                     }
  2520.  
  2521.                                     Width    = X - Left + 1;
  2522.                                     Height    = Y - Top + 1;
  2523.  
  2524.                                     Move(RPort,Left,Top);
  2525.                                     Draw(RPort,Left + Width - 1,Top);
  2526.                                     Draw(RPort,Left + Width - 1,Top + Height - 1);
  2527.                                     Draw(RPort,Left,Top + Height - 1);
  2528.                                     Draw(RPort,Left,Top + 1);
  2529.  
  2530.                                     DidBox = TRUE;
  2531.                                 }
  2532.  
  2533.                                 Code = NULL;
  2534.                             }
  2535.                         }
  2536.                     }
  2537.  
  2538.                     if(DidBox)
  2539.                     {
  2540.                         Move(RPort,Left,Top);
  2541.                         Draw(RPort,Left + Width - 1,Top);
  2542.                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2543.                         Draw(RPort,Left,Top + Height - 1);
  2544.                         Draw(RPort,Left,Top + 1);
  2545.                     }
  2546.  
  2547.                     SetDrMd(RPort,JAM1);
  2548.  
  2549.                     if(Width >= 2 && Height >= 2)
  2550.                     {
  2551.                         AreaLeft    = Left;
  2552.                         AreaTop        = Top;
  2553.  
  2554.                         AreaWidth    = Width;
  2555.                         AreaHeight    = Height;
  2556.  
  2557.                         NewCoords    = TRUE;
  2558.                         Running        = FALSE;
  2559.                         AreaActive    = TRUE;
  2560.                     }
  2561.                 }
  2562.             }
  2563.         }
  2564.     }
  2565.  
  2566.     ReportMouse(FALSE,Window);
  2567.  
  2568.     Window -> Flags &= ~WFLG_RMBTRAP;
  2569.  
  2570.     ClearPointer(Window);
  2571. }
  2572.  
  2573.     /* Zoom():
  2574.      *
  2575.      *    This routine handles the selection of an area on screen
  2576.      *    to zoom to later. Note that the area will be square.
  2577.      */
  2578.  
  2579. VOID
  2580. Zoom()
  2581. {
  2582.     struct IntuiMessage    *Massage;
  2583.     ULONG             Class,Code;
  2584.     UWORD             X,Y,LastX,LastY;
  2585.  
  2586.     SetClear(Window);
  2587.  
  2588.     Code = NULL;
  2589.  
  2590.     Window -> Flags |= WFLG_RMBTRAP;
  2591.  
  2592.     ReportMouse(TRUE,Window);
  2593.  
  2594.     SetAPen(RPort,1);
  2595.     SetDrMd(RPort,COMPLEMENT);
  2596.  
  2597.     LastX    = Window -> MouseX;
  2598.     LastY    = Window -> MouseY;
  2599.  
  2600.     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2601.     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2602.  
  2603.     while(Code != SELECTUP)
  2604.     {
  2605.         WaitPort(Window -> UserPort);
  2606.  
  2607.         if(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2608.         {
  2609.             Class    = Massage -> Class;
  2610.             Code    = Massage -> Code;
  2611.  
  2612.             X    = Massage -> MouseX;
  2613.             Y    = Massage -> MouseY;
  2614.  
  2615.             ReplyMsg(&Massage -> ExecMessage);
  2616.  
  2617.             if(Class == IDCMP_MOUSEMOVE)
  2618.             {
  2619.                 if(LastX != X)
  2620.                 {
  2621.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2622.                     DrawLine(RPort,X,0,X,Screen -> Height - 1);
  2623.                 }
  2624.  
  2625.                 if(LastY != Y)
  2626.                 {
  2627.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2628.                     DrawLine(RPort,0,Y,Screen -> Width - 1,Y);
  2629.                 }
  2630.  
  2631.                 LastX = X;
  2632.                 LastY = Y;
  2633.             }
  2634.  
  2635.             if(Class == IDCMP_MOUSEBUTTONS)
  2636.             {
  2637.                 if(Code == SELECTDOWN)
  2638.                 {
  2639.                     UWORD    Left,Top,Width = 0,Height = 0;
  2640.                     BYTE    DidBox = FALSE;
  2641.  
  2642.                     DrawLine(RPort,LastX,0,LastX,Screen -> Height - 1);
  2643.                     DrawLine(RPort,0,LastY,Screen -> Width - 1,LastY);
  2644.  
  2645.                     Left    = X;
  2646.                     Top    = Y;
  2647.  
  2648.                     SetAPen(RPort,1);
  2649.                     SetDrMd(RPort,COMPLEMENT);
  2650.  
  2651.                     while(Code != SELECTUP)
  2652.                     {
  2653.                         WaitPort(Window -> UserPort);
  2654.  
  2655.                         while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2656.                         {
  2657.                             Class    = Massage -> Class;
  2658.                             Code    = Massage -> Code;
  2659.  
  2660.                             Y    = Massage -> MouseY;
  2661.  
  2662.                             ReplyMsg(&Massage -> ExecMessage);
  2663.  
  2664.                             if(Class == IDCMP_MOUSEMOVE)
  2665.                             {
  2666.                                 if(Y > Top)
  2667.                                 {
  2668.                                     if(DidBox)
  2669.                                     {
  2670.                                         Move(RPort,Left,Top);
  2671.                                         Draw(RPort,Left + Width - 1,Top);
  2672.                                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2673.                                         Draw(RPort,Left,Top + Height - 1);
  2674.                                         Draw(RPort,Left,Top + 1);
  2675.                                     }
  2676.  
  2677.                                     Width = Height = Y - Top + 1;
  2678.  
  2679.                                     Move(RPort,Left,Top);
  2680.                                     Draw(RPort,Left + Width - 1,Top);
  2681.                                     Draw(RPort,Left + Width - 1,Top + Height - 1);
  2682.                                     Draw(RPort,Left,Top + Height - 1);
  2683.                                     Draw(RPort,Left,Top + 1);
  2684.  
  2685.                                     DidBox = TRUE;
  2686.                                 }
  2687.  
  2688.                                 Code = NULL;
  2689.                             }
  2690.                         }
  2691.                     }
  2692.  
  2693.                     if(DidBox)
  2694.                     {
  2695.                         Move(RPort,Left,Top);
  2696.                         Draw(RPort,Left + Width - 1,Top);
  2697.                         Draw(RPort,Left + Width - 1,Top + Height - 1);
  2698.                         Draw(RPort,Left,Top + Height - 1);
  2699.                         Draw(RPort,Left,Top + 1);
  2700.                     }
  2701.  
  2702.                     SetDrMd(RPort,JAM1);
  2703.  
  2704.                     if(Width >= 2 && Height >= 2)
  2705.                     {
  2706.                         BYTE Val;
  2707.  
  2708.                         SetWait(Window);
  2709.  
  2710.                         if(AnimRunning)
  2711.                             Val = MyEasyRequest("Yes|Abort|No","Transition will consist\nof %ld images.\n\nDo you wish to use the\ncurrent coordinates?",CalculateFrames(MinReal + (double)Left * RealStep,MinImaginary + (double)Top * ImaginaryStep,(double)Width * RealStep));
  2712.                         else
  2713.                             Val = MyEasyRequest("Yes|No","Do you wish to use the\ncurrent coordinates?");
  2714.  
  2715.                         switch(Val)
  2716.                         {
  2717.                             case 0:    break;
  2718.  
  2719.                             case 1:    MinReal        = MinReal + (double)Left * RealStep;
  2720.                                 MinImaginary    = MinImaginary + (double)Top * ImaginaryStep;
  2721.  
  2722.                                 RealWidth    = (double)Width * RealStep;
  2723.                                 ImaginaryHeight    = (double)Height * ImaginaryStep;
  2724.  
  2725.                                 RealStep    = RealWidth / (double)Window -> Width;
  2726.                                 ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  2727.  
  2728.                                 MainMinReal        = MinReal;
  2729.                                 MainMinImaginary    = MinImaginary;
  2730.                                 MainRealWidth        = RealWidth;
  2731.                                 MainImaginaryHeight    = ImaginaryHeight;
  2732.  
  2733.                                 NewCoords    = TRUE;
  2734.                                 Running        = FALSE;
  2735.                                 AreaActive    = FALSE;
  2736.                                 break;
  2737.  
  2738.                             case 2:    Running = FALSE;
  2739.                                 StopAnim();
  2740.                                 break;
  2741.                         }
  2742.                     }
  2743.                 }
  2744.             }
  2745.         }
  2746.     }
  2747.  
  2748.     ReportMouse(FALSE,Window);
  2749.  
  2750.     Window -> Flags &= ~WFLG_RMBTRAP;
  2751.  
  2752.     ClearPointer(Window);
  2753. }
  2754.  
  2755.     /* HandleEvent():
  2756.      *
  2757.      *    The global input event (menus, key, mouse, etc.) handler.
  2758.      */
  2759.  
  2760. VOID
  2761. HandleEvent()
  2762. {
  2763.     struct IntuiMessage    *Massage;
  2764.     struct MenuItem        *Item;
  2765.     ULONG             Class,Code,Qualifier,MenuItem,Selected;
  2766.     UBYTE            *DummyChar;
  2767.     BYTE             Waiting = FALSE;
  2768.  
  2769.     SetSignal(0,1 << Window -> UserPort -> mp_SigBit);
  2770.  
  2771.     do
  2772.     {
  2773.         while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  2774.         {
  2775.             Class        = Massage -> Class;
  2776.             Code        = Massage -> Code;
  2777.             Qualifier    = Massage -> Qualifier;
  2778.  
  2779.             ReplyMsg(&Massage -> ExecMessage);
  2780.  
  2781.             if(Class == IDCMP_MENUVERIFY)
  2782.                 Waiting = HoldIt = TRUE;
  2783.  
  2784.             if(Class == IDCMP_VANILLAKEY)
  2785.             {
  2786.                 if(Code == '\t')
  2787.                 {
  2788.                     if(!DoCycle)
  2789.                     {
  2790.                         Forward = TRUE;
  2791.  
  2792.                         DoCycle = TRUE;
  2793.                     }
  2794.                     else
  2795.                         DoCycle = FALSE;
  2796.                 }
  2797.             }
  2798.  
  2799.             if(Class == IDCMP_RAWKEY)
  2800.             {
  2801.                 UWORD    Palette[32];
  2802.                 BYTE    AltWheel = Wheel,i;
  2803.  
  2804.                 if(Code == CURSORLEFT)
  2805.                 {
  2806.                     DoCycle = FALSE;
  2807.  
  2808.                     Palette[0] = 0x000;
  2809.                     Palette[1] = 0xFFF;
  2810.  
  2811.                     if(UseWheel)
  2812.                     {
  2813.                         if(Wheel)
  2814.                             Wheel--;
  2815.                         else
  2816.                             Wheel = 74;
  2817.  
  2818.                         for(i = 2 ; i < 32 ; i++)
  2819.                         {
  2820.                             Palette[i] = Table[AltWheel];
  2821.  
  2822.                             AltWheel = (AltWheel + 1) % 75;
  2823.                         }
  2824.                     }
  2825.                     else
  2826.                     {
  2827.                         BYTE AltAdd = Add,Wrap = (1 << Depth) - 2;
  2828.  
  2829.                         if(Add)
  2830.                             Add--;
  2831.                         else
  2832.                             Add = Wrap - 1;
  2833.  
  2834.                         for(i = 2 ; i < (1 << Depth) ; i++)
  2835.                         {
  2836.                             Palette[i] = SinPalette[AltAdd + 2];
  2837.  
  2838.                             AltAdd = (AltAdd + 1) % Wrap;
  2839.                         }
  2840.                     }
  2841.  
  2842.                     LoadRGB4(VPort,Palette,1 << Depth);
  2843.                 }
  2844.  
  2845.                 if(Code == CURSORRIGHT)
  2846.                 {
  2847.                     DoCycle = FALSE;
  2848.  
  2849.                     Palette[0] = 0x000;
  2850.                     Palette[1] = 0xFFF;
  2851.  
  2852.                     if(UseWheel)
  2853.                     {
  2854.                         Wheel = (Wheel + 1) % 75;
  2855.  
  2856.                         for(i = 2 ; i < 32 ; i++)
  2857.                         {
  2858.                             Palette[i] = Table[AltWheel];
  2859.  
  2860.                             AltWheel = (AltWheel + 1) % 75;
  2861.                         }
  2862.                     }
  2863.                     else
  2864.                     {
  2865.                         BYTE AltAdd = Add,Wrap = (1 << Depth) - 2;
  2866.  
  2867.                         Add = (Add + 1) % Wrap;
  2868.  
  2869.                         for(i = 2 ; i < (1 << Depth) ; i++)
  2870.                         {
  2871.                             Palette[i] = SinPalette[AltAdd + 2];
  2872.  
  2873.                             AltAdd = (AltAdd + 1) % Wrap;
  2874.                         }
  2875.                     }
  2876.  
  2877.                     LoadRGB4(VPort,Palette,1 << Depth);
  2878.                 }
  2879.  
  2880.                 if(Code == CURSORUP)
  2881.                 {
  2882.                     Forward = TRUE;
  2883.  
  2884.                     DoCycle = TRUE;
  2885.                 }
  2886.  
  2887.                 if(Code == CURSORDOWN)
  2888.                 {
  2889.                     Forward = FALSE;
  2890.  
  2891.                     DoCycle = TRUE;
  2892.                 }
  2893.             }
  2894.  
  2895.             if(Class == IDCMP_MENUPICK)
  2896.             {
  2897.                 Waiting = HoldIt = FALSE;
  2898.  
  2899.                 if(GotClip)
  2900.                 {
  2901.                     BltBitMap(BackupBitMap,0,0,RPort -> BitMap,(Square - 25 * 8) >> 1,(Square - 8) >> 1,8 * 25,8,0xC0,0xFF,NULL);
  2902.  
  2903.                     GotClip = FALSE;
  2904.                 }
  2905.  
  2906.                 MenuItem = Code;
  2907.  
  2908.                 while(MenuItem != MENUNULL)
  2909.                 {
  2910.                     if(Item = ItemAddress(Menu,MenuItem))
  2911.                     {
  2912.                         Selected = (ULONG)MENU_USERDATA(Item);
  2913.  
  2914.                         switch(Selected)
  2915.                         {
  2916.                             case MEN_OPEN:    BlockWindow();
  2917.  
  2918.                                     strcpy(NameBuffer,LastName);
  2919.  
  2920.                                     DummyChar = PathPart(NameBuffer);
  2921.  
  2922.                                     *DummyChar = 0;
  2923.  
  2924.                                     if(GetFile("Open Picture",NameBuffer,FilePart(LastName),NameBuffer,"~(#?.info)",FALSE))
  2925.                                     {
  2926.                                         struct IFFHandle    *Handle;
  2927.                                         struct BitMap        *BitMap;
  2928.  
  2929.                                         if(Handle = OpenImageFile(NameBuffer))
  2930.                                         {
  2931.                                             struct BitMapHeader    BitMapHeader;
  2932.                                             struct MandelInfo    TempMandelInfo;
  2933.                                             BYTE            Colours = 1 << Depth,GotImage = FALSE;
  2934.  
  2935.                                             if(ReadImageHeader(Handle,&GlobalMode,&Colours,ColourTable,&BitMapHeader,&TempMandelInfo))
  2936.                                             {
  2937.                                                 if(BitMapHeader . w == Window -> Width && BitMapHeader . h == Window -> Height)
  2938.                                                 {
  2939.                                                     if(BitMap = CreateBitMap(BitMapHeader . nPlanes,BitMapHeader . w,BitMapHeader . h))
  2940.                                                     {
  2941.                                                         if(ReadImageBody(Handle,BitMap,&BitMapHeader))
  2942.                                                         {
  2943.                                                             WORD i,Height = Screen -> Height;
  2944.  
  2945.                                                             if(GetVPModeID(&Screen -> ViewPort) & LACE)
  2946.                                                                 Height >>= 1;
  2947.  
  2948.                                                             DoCycle = FALSE;
  2949.  
  2950.                                                             GetScreenPalette();
  2951.  
  2952.                                                             FadeTo(&Screen -> ViewPort,ScreenPalette,ColourTable,1 << Depth,0,0);
  2953.  
  2954.                                                             switch(Random(6))
  2955.                                                             {
  2956.                                                                 case 0:    for(i = 0 ; i < (Square >> 1) ; i++)
  2957.                                                                     {
  2958.                                                                         WaitLine(Height);
  2959.  
  2960.                                                                         BltBitMapRastPort(BitMap,0,2 * i,      RPort,0,2 * i,      Screen -> Width,1,0xC0);
  2961.                                                                         BltBitMapRastPort(BitMap,0,Square - 1 - 2 * i,RPort,0,Square - 1 - 2 * i,Screen -> Width,1,0xC0);
  2962.                                                                     }
  2963.  
  2964.                                                                     break;
  2965.  
  2966.                                                                 case 1:    for(i = 0 ; i < (Square >> 1) ; i++)
  2967.                                                                     {
  2968.                                                                         WaitLine(Height);
  2969.  
  2970.                                                                         BltBitMapRastPort(BitMap,2 * i,0,      RPort,2 * i,0,1,      Screen -> Height,0xC0);
  2971.                                                                         BltBitMapRastPort(BitMap,Square - 1 - 2 * i,0,RPort,Square - 1 - 2 * i,0,1,Screen -> Height,0xC0);
  2972.                                                                     }
  2973.  
  2974.                                                                     break;
  2975.  
  2976.                                                                 case 2:    for(i = 0 ; i < (Square >> 1) ; i++)
  2977.                                                                     {
  2978.                                                                         WaitLine(Height);
  2979.  
  2980.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,((Square >> 1) - i) * 2,1,0xC0);
  2981.                                                                         BltBitMapRastPort(BitMap,i,Square - 1 - i,RPort,i,Square - 1 - i,((Square >> 1) - i) * 2,1,0xC0);
  2982.  
  2983.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,1,((Square >> 1) - i) * 2,0xC0);
  2984.                                                                         BltBitMapRastPort(BitMap,Square - 1 - i,i,RPort,Square - 1 - i,i,1,((Square >> 1) - i) * 2,0xC0);
  2985.                                                                     }
  2986.  
  2987.                                                                     break;
  2988.  
  2989.                                                                 case 3:    for(i = (Square >> 1) - 1 ; i >= 0 ; i--)
  2990.                                                                     {
  2991.                                                                         WaitLine(Height);
  2992.  
  2993.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,((Square >> 1) - i) * 2,1,0xC0);
  2994.                                                                         BltBitMapRastPort(BitMap,i,Square - 1 - i,RPort,i,Square - 1 - i,((Square >> 1) - i) * 2,1,0xC0);
  2995.  
  2996.                                                                         BltBitMapRastPort(BitMap,i,i,RPort,i,i,1,((Square >> 1) - i) * 2,0xC0);
  2997.                                                                         BltBitMapRastPort(BitMap,Square - 1 - i,i,RPort,Square - 1 - i,i,1,((Square >> 1) - i) * 2,0xC0);
  2998.                                                                     }
  2999.  
  3000.                                                                     break;
  3001.  
  3002.                                                                 case 4:    for(i = 0 ; i < Square ; i++)
  3003.                                                                     {
  3004.                                                                         WaitLine(Height);
  3005.  
  3006.                                                                         BltBitMapRastPort(BitMap,      i,  0,RPort,      i,  0,1,(Square >> 1),0xC0);
  3007.                                                                         BltBitMapRastPort(BitMap,Square - 1 - i,(Square >> 1),RPort,Square - 1 - i,(Square >> 1),1,(Square >> 1),0xC0);
  3008.                                                                     }
  3009.  
  3010.                                                                     break;
  3011.  
  3012.                                                                 case 5:    for(i = 0 ; i < Square ; i++)
  3013.                                                                     {
  3014.                                                                         WaitLine(Height);
  3015.  
  3016.                                                                         BltBitMapRastPort(BitMap,  0,      i,RPort,  0,      i,(Square >> 1),1,0xC0);
  3017.                                                                         BltBitMapRastPort(BitMap,(Square >> 1),Square - 1 - i,RPort,(Square >> 1),Square - 1 - i,(Square >> 1),1,0xC0);
  3018.                                                                     }
  3019.  
  3020.                                                                     break;
  3021.                                                             }
  3022.  
  3023.                                                             Wheel = 0;
  3024.  
  3025.                                                             for(i = 0 ; i < 75 ; i++)
  3026.                                                             {
  3027.                                                                 if(ColourTable[2] == Table[i])
  3028.                                                                 {
  3029.                                                                     Wheel = i;
  3030.                                                                     break;
  3031.                                                                 }
  3032.                                                             }
  3033.  
  3034.                                                             if(TempMandelInfo . Iterations)
  3035.                                                             {
  3036.                                                                 MainMinReal        = MinReal        = TempMandelInfo . MinReal;
  3037.                                                                 MainMinImaginary    = MinImaginary        = TempMandelInfo . MinImaginary;
  3038.                                                                 MainRealWidth        = RealWidth        = TempMandelInfo . RealWidth;
  3039.                                                                 MainImaginaryHeight    = ImaginaryHeight    = TempMandelInfo . ImaginaryHeight;
  3040.                                                                 MaxIteration                    = TempMandelInfo . Iterations;
  3041.  
  3042.                                                                 IterationSetup();
  3043.  
  3044.                                                                 RealStep    = RealWidth / (double)Window -> Width;
  3045.                                                                 ImaginaryStep    = ImaginaryHeight / (double)Window -> Height;
  3046.                                                             }
  3047.                                                             else
  3048.                                                                 MyEasyRequest("Continue","Could not read image\ncoordinates, previous values\nremain untouched.");
  3049.  
  3050.                                                             strcpy(LastName,NameBuffer);
  3051.  
  3052.                                                             Running = FALSE;
  3053.  
  3054.                                                             AreaActive = FALSE;
  3055.  
  3056.                                                             GotImage = TRUE;
  3057.                                                         }
  3058.                                                         else
  3059.                                                             MyEasyRequest("Continue","Error reading file\n%s.",FilePart(NameBuffer));
  3060.  
  3061.                                                         DeleteBitMap(BitMap);
  3062.                                                     }
  3063.                                                     else
  3064.                                                         MyEasyRequest("Continue","Not enough memory!");
  3065.                                                 }
  3066.                                                 else
  3067.                                                 {
  3068.                                                     if(BitMapHeader . w == BitMapHeader . h && !(BitMapHeader . h % 4))
  3069.                                                     {
  3070.                                                         if(BitMap = CreateBitMap(BitMapHeader . nPlanes,BitMapHeader . w,BitMapHeader . h))
  3071.                                                         {
  3072.                                                             if(ReadImageBody(Handle,BitMap,&BitMapHeader))
  3073.                                                             {
  3074.                                                                 WORD i;
  3075.  
  3076.                                                                 Wheel = 0;
  3077.  
  3078.                                                                 for(i = 0 ; i < 75 ; i++)
  3079.                                                                 {
  3080.                                                                     if(ColourTable[2] == Table[i])
  3081.                                                                     {
  3082.                                                                         Wheel = i;
  3083.                                                                         break;
  3084.                                                                     }
  3085.                                                                 }
  3086.  
  3087.                                                                 if(TempMandelInfo . Iterations)
  3088.                                                                 {
  3089.                                                                     MainMinReal        = MinReal        = TempMandelInfo . MinReal;
  3090.                                                                     MainMinImaginary    = MinImaginary        = TempMandelInfo . MinImaginary;
  3091.                                                                     MainRealWidth        = RealWidth        = TempMandelInfo . RealWidth;
  3092.                                                                     MainImaginaryHeight    = ImaginaryHeight    = TempMandelInfo . ImaginaryHeight;
  3093.                                                                     MaxIteration                    = TempMandelInfo . Iterations;
  3094.  
  3095.                                                                     RealStep        = RealWidth / (double)Window -> Width;
  3096.                                                                     ImaginaryStep        = ImaginaryHeight / (double)Window -> Height;
  3097.                                                                 }
  3098.                                                                 else
  3099.                                                                     MyEasyRequest("Continue","Could not read image\ncoordinates, previous values\nremain untouched.");
  3100.  
  3101.                                                                 strcpy(LastName,NameBuffer);
  3102.  
  3103.                                                                 Running        = FALSE;
  3104.                                                                 AreaActive    = FALSE;
  3105.                                                                 NewMode        = TRUE;
  3106.                                                                 DoCycle        = FALSE;
  3107.  
  3108.                                                                 GlobalBitMap    = BitMap;
  3109.                                                                 GlobalHeader    = BitMapHeader;
  3110.                                                             }
  3111.                                                             else
  3112.                                                             {
  3113.                                                                 MyEasyRequest("Continue","Error reading file\n%s.",FilePart(NameBuffer));
  3114.  
  3115.                                                                 DeleteBitMap(BitMap);
  3116.                                                             }
  3117.                                                         }
  3118.                                                         else
  3119.                                                             MyEasyRequest("Continue","Not enough memory!");
  3120.                                                     }
  3121.                                                     else
  3122.                                                         MyEasyRequest("Continue","Picture has wrong size!");
  3123.                                                 }
  3124.                                             }
  3125.                                             else
  3126.                                                 MyEasyRequest("Continue","Error reading file\n%s.",FilePart(NameBuffer));
  3127.  
  3128.                                             CloseImageFile(Handle);
  3129.                                         }
  3130.                                         else
  3131.                                             MyEasyRequest("Continue","Could not open file\n%s.",FilePart(NameBuffer));
  3132.                                     }
  3133.  
  3134.                                     ReleaseWindow();
  3135.  
  3136.                                     break;
  3137.  
  3138.                             case MEN_SAVE:    BlockWindow();
  3139.  
  3140.                                     if(NameBuffer[0])
  3141.                                         goto SaveIt;
  3142.  
  3143.                             case MEN_SAVEAS:BlockWindow();
  3144.  
  3145.                                     strcpy(NameBuffer,LastName);
  3146.  
  3147.                                     DummyChar = PathPart(NameBuffer);
  3148.  
  3149.                                     *DummyChar = 0;
  3150.  
  3151.                                     if(GetFile("Save Picture As",NameBuffer,FilePart(LastName),NameBuffer,"~(#?.info)",TRUE))
  3152.                                     {
  3153. SaveIt:                                        MandelInfo . MinReal        = MinReal;
  3154.                                         MandelInfo . MinImaginary    = MinImaginary;
  3155.                                         MandelInfo . RealWidth        = RealWidth;
  3156.                                         MandelInfo . ImaginaryHeight    = ImaginaryHeight;
  3157.                                         MandelInfo . Iterations        = MaxIteration;
  3158.  
  3159.                                         if(!SaveBitMap(RPort -> BitMap,&Screen -> ViewPort,0,0,Window -> Width,Window -> Height,Screen -> Width,Screen -> Height,NameBuffer,&MandelInfo))
  3160.                                             MyEasyRequest("Continue","Could not save file\n%s.",FilePart(NameBuffer));
  3161.                                         else
  3162.                                         {
  3163.                                             if(!ThisProcess -> pr_CLI)
  3164.                                                 PutDiskObject(NameBuffer,&PictureIcon);
  3165.  
  3166.                                             strcpy(LastName,NameBuffer);
  3167.                                         }
  3168.                                     }
  3169.  
  3170.                                     ReleaseWindow();
  3171.                                     break;
  3172.  
  3173.                             case MEN_PRI0:    SetTaskPri(ThisProcess,-5);
  3174.                                     break;
  3175.  
  3176.                             case MEN_PRI1:    SetTaskPri(ThisProcess,0);
  3177.                                     break;
  3178.  
  3179.                             case MEN_PRI2:    SetTaskPri(ThisProcess,5);
  3180.                                     break;
  3181.  
  3182.                             case MEN_PLAY:    BlockWindow();
  3183.  
  3184.                                     ReplayAnim();
  3185.  
  3186.                                     ReleaseWindow();
  3187.  
  3188.                                     break;
  3189.  
  3190.                             case MEN_START:    if(!AnimRunning)
  3191.                                     {
  3192.                                         Running        = FALSE;
  3193.                                         FullPicture    = FALSE;
  3194.                                         AnimRunning    = TRUE;
  3195.                                     }
  3196.  
  3197.                                     break;
  3198.  
  3199.                             case MEN_STOP:    BlockWindow();
  3200.  
  3201.                                     StopAnim();
  3202.  
  3203.                                     Running = FALSE;
  3204.  
  3205.                                     FullPicture = FALSE;
  3206.  
  3207.                                     ReleaseWindow();
  3208.  
  3209.                                     break;
  3210.  
  3211.                             case MEN_SCROLL:BlockWindow();
  3212.  
  3213.                                     MaxScrollPanel();
  3214.  
  3215.                                     ReleaseWindow();
  3216.  
  3217.                                     break;
  3218.  
  3219.                             case MEN_FRAME:    if(Item -> Flags & CHECKED)
  3220.                                         Frame = TRUE;
  3221.                                     else
  3222.                                         Frame = FALSE;
  3223.  
  3224.                                     break;
  3225.  
  3226.                             case MEN_INCLUDE:
  3227.                                     if(Item -> Flags & CHECKED)
  3228.                                         Include = TRUE;
  3229.                                     else
  3230.                                         Include = FALSE;
  3231.  
  3232.                                     break;
  3233.  
  3234.                             case MEN_RESOLUTION:
  3235.                                     NewMode = TRUE;
  3236.                                     Running = FALSE;
  3237.                                     DoCycle = FALSE;
  3238.                                     break;
  3239.  
  3240.                             case MEN_ABOUT:    BlockWindow();
  3241.  
  3242.                                     MyEasyRequest("So what?","       MandelSquare\n\nYet another Mandelbrot set\n   exploration program\n\n        Written by\n   Olaf `Olsen' Barthel\n\n     © Copyright 1991\n");
  3243.  
  3244.                                     ReleaseWindow();
  3245.                                     break;
  3246.  
  3247.                             case MEN_QUIT:    BlockWindow();
  3248.  
  3249.                                     if(MyEasyRequest("Yes|No","Do you really wish to\nleave this program?"))
  3250.                                         CloseAll(RETURN_OK);
  3251.  
  3252.                                     ReleaseWindow();
  3253.                                     break;
  3254.  
  3255.                             case MEN_ZOOM:    Zoom();
  3256.                                     break;
  3257.  
  3258.                             case MEN_CLIP:    AreaZoom();
  3259.                                     Faster = TRUE;
  3260.                                     break;
  3261.  
  3262.                             case MEN_RERUN:    AreaZoom();
  3263.                                     Faster = FALSE;
  3264.                                     break;
  3265.  
  3266.                             case MEN_PRECISE:
  3267.                                     if(Item -> Flags & CHECKED)
  3268.                                         Precise = TRUE;
  3269.                                     else
  3270.                                         Precise = FALSE;
  3271.  
  3272.                                     break;
  3273.  
  3274.                             case MEN_COORDS:BlockWindow();
  3275.                                     Coords();
  3276.                                     ReleaseWindow();
  3277.                                     break;
  3278.  
  3279.                             case MEN_PALETTE:
  3280.                                     BlockWindow();
  3281.                                     Palette();
  3282.                                     ReleaseWindow();
  3283.                                     break;
  3284.  
  3285.                             case MEN_SPEC:    DoCycle = FALSE;
  3286.  
  3287.                                     if(Item -> Flags & CHECKED)
  3288.                                         UseWheel = TRUE;
  3289.                                     else
  3290.                                         UseWheel = FALSE;
  3291.  
  3292.                                     GetScreenPalette();
  3293.  
  3294.                                     if(UseWheel)
  3295.                                         FadeTo(&Screen -> ViewPort,ScreenPalette,WheelPalette,1 << Depth,0,0);
  3296.                                     else
  3297.                                         FadeTo(&Screen -> ViewPort,ScreenPalette,SinPalette,1 << Depth,0,0);
  3298.  
  3299.                                     break;
  3300.  
  3301.                             case MEN_RUN:    Running ^= TRUE;
  3302.  
  3303.                                     if(!Running)
  3304.                                         FullPicture = FALSE;
  3305.  
  3306.                                     break;
  3307.  
  3308.                             default:    if(Selected >= 1 && Selected <= 16)
  3309.                                         MaxIteration = (1 << Selected);
  3310.  
  3311.                                     break;
  3312.                         }
  3313.  
  3314.                         MenuItem = Item -> NextSelect;
  3315.                     }
  3316.                     else
  3317.                         break;
  3318.                 }
  3319.             }
  3320.         }
  3321.  
  3322.         if(Waiting)
  3323.             WaitPort(Window -> UserPort);
  3324.     }
  3325.     while(Waiting);
  3326. }
  3327.  
  3328. #if 0
  3329.  
  3330.     /* Iterate(double RealValue,double ImaginaryValue):
  3331.      *
  3332.      *    This is the `C' version of the Iterate routine
  3333.      *    present in Iterate.asm. I've commented it out
  3334.      *    and included it only for historical reasons.
  3335.      */
  3336.  
  3337. BYTE
  3338. Iterate(double RealValue,double ImaginaryValue)
  3339. {
  3340.     double    Real = 0,Imaginary = 0,RealTemp,ImaginaryTemp;
  3341.     WORD    i = 0;
  3342.  
  3343.     for(;;)
  3344.     {
  3345.         ImaginaryTemp     = Imaginary * Imaginary;
  3346.         RealTemp    = Real * Real;
  3347.  
  3348.         if(fabs(RealTemp + ImaginaryTemp) > 4.0)
  3349.             return(Wave[i]);
  3350.  
  3351.         if(++i >= MaxIteration)
  3352.             return(0);
  3353.  
  3354.         Imaginary    = 2.0 * Real * Imaginary + ImaginaryValue;
  3355.         Real        = RealTemp - ImaginaryTemp + RealValue;
  3356.     }
  3357. }
  3358.  
  3359. #endif
  3360.  
  3361.     /* Mandelbrot():
  3362.      *
  3363.      *    The recursive image generation routine.
  3364.      */
  3365.  
  3366. VOID
  3367. Mandelbrot(double MinReal,double MinImaginary,double RealStep,double ImaginaryStep,LONG Left,LONG Top,LONG Width,LONG Height)
  3368. {
  3369.     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3370.         HandleEvent();
  3371.  
  3372.     if(Running)
  3373.     {
  3374.         BYTE Colours[4],LastColour,Ident = TRUE;
  3375.         WORD Positions[4][2],i;
  3376.  
  3377.             /* Set up pixel positions. */
  3378.  
  3379.         Positions[0][0] = Left;
  3380.         Positions[0][1] = Top;
  3381.  
  3382.         Positions[1][0] = Left + Width - 1;
  3383.         Positions[1][1] = Top;
  3384.  
  3385.         Positions[2][0] = Left + Width - 1;
  3386.         Positions[2][1] = Top + Height - 1;
  3387.  
  3388.         Positions[3][0] = Left;
  3389.         Positions[3][1] = Top + Height - 1;
  3390.  
  3391.         for(i = 0 ; i < 4 ; i++)
  3392.         {
  3393.                 /* Calculate colour values for each pixel. */
  3394.  
  3395.             Colours[i] = Iterate(MinReal + RealStep * (double)Positions[i][0],MinImaginary + ImaginaryStep * (double)Positions[i][1]);
  3396.  
  3397.                 /* Are all colour identical? */
  3398.  
  3399.             if(Ident)
  3400.             {
  3401.                 if(!i)
  3402.                     LastColour = Colours[i];
  3403.                 else
  3404.                 {
  3405.                     if(Colours[i] != LastColour)
  3406.                         Ident = FALSE;
  3407.                     else
  3408.                         LastColour = Colours[i];
  3409.                 }
  3410.             }
  3411.         }
  3412.  
  3413.             /* If all colour happen to be identical, fill the
  3414.              * are in the given colour.
  3415.              */
  3416.  
  3417.         if(Ident)
  3418.         {
  3419.                 /* If extra precision is selected, also check
  3420.                  * if all the pixels on the margin of the
  3421.                  * current square are in the same colour.
  3422.                  */
  3423.  
  3424.             if(Precise)
  3425.             {
  3426.                 WORD j,PositionBackup[4][2];
  3427.  
  3428.                 CopyMem(Positions,PositionBackup,sizeof(PositionBackup));
  3429.  
  3430.                 for(i = 0 ; i < Width - 1 ; i++)
  3431.                 {
  3432.                     PositionBackup[0][0]++;
  3433.                     PositionBackup[1][1]++;
  3434.                     PositionBackup[2][0]--;
  3435.                     PositionBackup[3][1]--;
  3436.  
  3437.                     for(j = 0 ; j < 4 ; j++)
  3438.                     {
  3439.                         if(Iterate(MinReal + RealStep * (double)PositionBackup[j][0],MinImaginary + ImaginaryStep * (double)PositionBackup[j][1]) != Colours[0])
  3440.                             goto Full;
  3441.                     }
  3442.                 }
  3443.             }
  3444.  
  3445.                 /* If necessary fill the square. */
  3446.  
  3447.             if(Colours[0])
  3448.             {
  3449.                 if(RPort -> FgPen != Colours[0])
  3450.                     SetAPen(RPort,Colours[0]);
  3451.  
  3452.                 RectFill(RPort,Left,Top,Left + Width - 1,Top + Height - 1);
  3453.             }
  3454.         }
  3455.         else
  3456.         {
  3457.                 /* If not already down at minimum level,
  3458.                  * split the square again.
  3459.                  */
  3460.  
  3461. Full:            if(Width > 2 && Height > 2)
  3462.             {
  3463.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left,Top,Width >> 1,Height >> 1);
  3464.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left + (Width >> 1),Top,Width >> 1,Height >> 1);
  3465.  
  3466.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left,Top + (Height >> 1),Width >> 1,Height >> 1);
  3467.                 Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Left + (Width >> 1),Top + (Height >> 1),Width >> 1,Height >> 1);
  3468.             }
  3469.             else
  3470.             {
  3471.                 register struct BitMap *BitMap = RPort -> BitMap;
  3472.  
  3473.                     /* Set the pixels. */
  3474.  
  3475.                 for(i = 0 ; i < 4 ; i++)
  3476.                 {
  3477.                     if(Colours[i])
  3478.                         Plot(BitMap,Positions[i][0],Positions[i][1],Colours[i]);
  3479.                 }
  3480.             }
  3481.         }
  3482.     }
  3483. }
  3484.  
  3485.     /* RunMandelbrot():
  3486.      *
  3487.      *    This is the recursive image generation driver, it
  3488.      *    remembers the time it took to generate the image and
  3489.      *    calls the recursive image generation routine.
  3490.      */
  3491.  
  3492. VOID
  3493. RunMandelbrot(double MinReal,double MaxReal,double MinImaginary,double MaxImaginary,LONG Width,LONG Height)
  3494. {
  3495.     double        RealStep,ImaginaryStep;
  3496.     UBYTE        TimeBuffer[40];
  3497.     struct timeval    TimeVal;
  3498.  
  3499.     GetTime();
  3500.  
  3501.     TimeVal = TimeRequest -> tr_time;
  3502.  
  3503.     RealStep    = (MaxReal - MinReal) / (double)Width;
  3504.     ImaginaryStep    = (MaxImaginary - MinImaginary) / (double)Height;
  3505.  
  3506.     FullPicture = TRUE;
  3507.  
  3508.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,0,Window -> Width >> 1,Window -> Height >> 1);
  3509.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,0,Window -> Width >> 1,Window -> Height >> 1);
  3510.  
  3511.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,0,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  3512.     Mandelbrot(MinReal,MinImaginary,RealStep,ImaginaryStep,Window -> Width >> 1,Window -> Height >> 1,Window -> Width >> 1,Window -> Height >> 1);
  3513.  
  3514.     GetTime();
  3515.  
  3516.     SubTime(&TimeRequest -> tr_time,&TimeVal);
  3517.  
  3518.     BltBitMap(RPort -> BitMap,(Square - 25 * 8) >> 1,(Square - 8) >> 1,BackupBitMap,0,0,8 * 25,8,0xC0,0xFF,NULL);
  3519.  
  3520.     GotClip = TRUE;
  3521.  
  3522.     SetAPen(RPort,1);
  3523.     SetDrMd(RPort,JAM1);
  3524.  
  3525.     TimeVal = TimeRequest -> tr_time;
  3526.  
  3527.     sprintf(TimeBuffer,"Duration %2d:%02d:%02d Minutes",(TimeVal . tv_secs % 86400) / 3600,(TimeVal . tv_secs % 3600) / 60,TimeVal . tv_secs % 60);
  3528.  
  3529.     Move(RPort,(Square - 25 * 8) >> 1,((Square - 8) >> 1) + 6);
  3530.     Text(RPort,TimeBuffer,25);
  3531.  
  3532.     Running = FALSE;
  3533. }
  3534.  
  3535.     /* RunAreaMandelbrot(double RealStep,double ImaginaryStep):
  3536.      *
  3537.      *    This is the iterative image generation routine,
  3538.      *    unlike the routines above it generates the image
  3539.      *    pixel by pixel and is not limited to a square
  3540.      *    drawing area.
  3541.      */
  3542.  
  3543. VOID
  3544. RunAreaMandelbrot(double RealStep,double ImaginaryStep)
  3545. {
  3546.     double         RealValue,ImaginaryValue;
  3547.     WORD         x,y;
  3548.     UBYTE         TimeBuffer[40];
  3549.     struct BitMap    *BitMap = RPort -> BitMap;
  3550.     struct timeval     TimeVal;
  3551.     BYTE         Colour;
  3552.  
  3553.     GetTime();
  3554.  
  3555.     TimeVal = TimeRequest -> tr_time;
  3556.  
  3557.     ImaginaryValue = MinImaginary + ImaginaryStep * (double)AreaTop;
  3558.  
  3559.         /* `Faster' actually only means that before a pixel
  3560.          * is drawn the approriate spot is checked to see
  3561.          * if there is not already a pixel in place.
  3562.          */
  3563.  
  3564.     if(Faster)
  3565.     {
  3566.         for(y = 0 ; (y < AreaHeight) && Running ; y++)
  3567.         {
  3568.             RealValue = MinReal + RealStep * (double)AreaLeft;
  3569.  
  3570.             for(x = 0 ; (x < AreaWidth) && Running ; x++)
  3571.             {
  3572.                 if(!Test(BitMap,AreaLeft + x,AreaTop + y))
  3573.                 {
  3574.                     if((Colour = Iterate(RealValue,ImaginaryValue)))
  3575.                         Plot(BitMap,AreaLeft + x,AreaTop + y,Colour);
  3576.                 }
  3577.  
  3578.                 RealValue += RealStep;
  3579.  
  3580.                 if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3581.                     HandleEvent();
  3582.             }
  3583.  
  3584.             ImaginaryValue += ImaginaryStep;
  3585.         }
  3586.     }
  3587.     else
  3588.     {
  3589.             /* These loops will calculate the image pixel
  3590.              * by pixel without skipping already set areas.
  3591.              * The first check insures that the drawing area
  3592.              * is as wide as the screen which means that
  3593.              * we are able to generate the pixels in fast
  3594.              * ram and to copy them to chip ram when done.
  3595.              */
  3596.  
  3597.         if(AreaWidth == Window -> Width && LineBitMap . Planes[0])
  3598.         {
  3599.             for(y = 0 ; (y < AreaHeight) && Running ; y++)
  3600.             {
  3601.                 RealValue = MinReal + RealStep * (double)AreaLeft;
  3602.  
  3603.                 for(x = 0 ; (x < AreaWidth) && Running ; x++)
  3604.                 {
  3605.                     if((Colour = Iterate(RealValue,ImaginaryValue)))
  3606.                         Set(LineBitMap . Planes,AreaLeft + x,Colour,LineBitMap . Depth);
  3607.                     else
  3608.                         Set(LineBitMap . Planes,AreaLeft + x,0,LineBitMap . Depth);
  3609.  
  3610.                     RealValue += RealStep;
  3611.  
  3612.                     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3613.                         HandleEvent();
  3614.                 }
  3615.  
  3616.                 if(Running)
  3617.                     CopyLine(&LineBitMap,AreaTop + y);
  3618.  
  3619.                 ImaginaryValue += ImaginaryStep;
  3620.             }
  3621.         }
  3622.         else
  3623.         {
  3624.             for(y = 0 ; (y < AreaHeight) && Running ; y++)
  3625.             {
  3626.                 RealValue = MinReal + RealStep * (double)AreaLeft;
  3627.  
  3628.                 for(x = 0 ; (x < AreaWidth) && Running ; x++)
  3629.                 {
  3630.                     if((Colour = Iterate(RealValue,ImaginaryValue)))
  3631.                         Plot(BitMap,AreaLeft + x,AreaTop + y,Colour);
  3632.  
  3633.                     RealValue += RealStep;
  3634.  
  3635.                     if(SetSignal(0,0) & (1 << Window -> UserPort -> mp_SigBit))
  3636.                         HandleEvent();
  3637.                 }
  3638.  
  3639.                 ImaginaryValue += ImaginaryStep;
  3640.             }
  3641.         }
  3642.     }
  3643.  
  3644.     GetTime();
  3645.  
  3646.     SubTime(&TimeRequest -> tr_time,&TimeVal);
  3647.  
  3648.     BltBitMap(RPort -> BitMap,(Square - 25 * 8) >> 1,(Square - 8) >> 1,BackupBitMap,0,0,8 * 25,8,0xC0,0xFF,NULL);
  3649.  
  3650.     GotClip = TRUE;
  3651.  
  3652.     SetAPen(RPort,1);
  3653.     SetDrMd(RPort,JAM1);
  3654.  
  3655.     TimeVal = TimeRequest -> tr_time;
  3656.  
  3657.     sprintf(TimeBuffer,"Duration %2d:%02d:%02d Minutes",(TimeVal . tv_secs % 86400) / 3600,(TimeVal . tv_secs % 3600) / 60,TimeVal . tv_secs % 60);
  3658.  
  3659.     Move(RPort,(Square - 25 * 8) >> 1,((Square - 8) >> 1) + 6);
  3660.     Text(RPort,TimeBuffer,25);
  3661.  
  3662.     Running = FALSE;
  3663.  
  3664.     Faster = TRUE;
  3665. }
  3666.  
  3667.     /* main():
  3668.      *
  3669.      *    The notorious main routine.
  3670.      */
  3671.  
  3672. VOID __stdargs
  3673. main()
  3674. {
  3675.     struct IFFHandle    *Handle;
  3676.     struct BitMap        *BitMap;
  3677.     BYTE             GotImage = FALSE,IsAnim = FALSE;
  3678.  
  3679.         /* Open the required resources. */
  3680.  
  3681.     OpenAll();
  3682.  
  3683.     MinReal        = -RealWidth / 2;
  3684.     MinImaginary    = -ImaginaryHeight / 2;
  3685.  
  3686.     DummyBuffer[0] = 0;
  3687.  
  3688.         /* Pick up any selected images if run from Workbench. */
  3689.  
  3690.     if(!ThisProcess -> pr_CLI)
  3691.     {
  3692.         extern struct WBStartup *WBenchMsg;
  3693.  
  3694.         DefaultTool[0] = 0;
  3695.  
  3696.             /* Build new default tool name. */
  3697.  
  3698.         if(NameFromLock(WBenchMsg -> sm_ArgList[0] . wa_Lock,DefaultTool,256))
  3699.         {
  3700.             if(!AddPart(DefaultTool,WBenchMsg -> sm_ArgList[0] . wa_Name,256))
  3701.                 DefaultTool[0] = 0;
  3702.         }
  3703.  
  3704.         if(!DefaultTool[0])
  3705.             strcpy(DefaultTool,"MandelSquare");
  3706.  
  3707.         PictureIcon . do_DefaultTool    = DefaultTool;
  3708.         AnimIcon . do_DefaultTool    = DefaultTool;
  3709.  
  3710.             /* Called with Workbench arguments? */
  3711.  
  3712.         if(WBenchMsg -> sm_NumArgs > 1)
  3713.         {
  3714.                 /* Construct the full name. */
  3715.  
  3716.             if(NameFromLock(WBenchMsg -> sm_ArgList[1] . wa_Lock,DummyBuffer,256))
  3717.             {
  3718.                 if(!AddPart(DummyBuffer,WBenchMsg -> sm_ArgList[1] . wa_Name,256))
  3719.                     DummyBuffer[0] = 0;
  3720.                 else
  3721.                 {
  3722.                     struct DiskObject *Icon;
  3723.  
  3724.                         /* Read the icon and try to figure
  3725.                          * out whether the corresponding
  3726.                          * file is an animation or just
  3727.                          * a plain image.
  3728.                          */
  3729.  
  3730.                     if(Icon = GetDiskObject(DummyBuffer))
  3731.                     {
  3732.                         UBYTE *Value;
  3733.  
  3734.                         if(Value = FindToolType(Icon -> do_ToolTypes,"FILETYPE"))
  3735.                         {
  3736.                             if(!stricmp(Value,"ANIM"))
  3737.                                 IsAnim = TRUE;
  3738.                         }
  3739.  
  3740.                         FreeDiskObject(Icon);
  3741.                     }
  3742.                 }
  3743.             }
  3744.             else
  3745.                 DummyBuffer[0] = 0;
  3746.         }
  3747.     }
  3748.  
  3749.         /* No chance, use the default image. */
  3750.  
  3751.     if(!DummyBuffer[0])
  3752.         strcpy(DummyBuffer,"MandelSquare.Title");
  3753.  
  3754.         /* Try to read the selected image. */
  3755.  
  3756.     if(Handle = OpenImageFile(DummyBuffer))
  3757.     {
  3758.         struct BitMapHeader    BitMapHeader;
  3759.         struct MandelInfo    TempMandelInfo;
  3760.         BYTE            Colours = 1 << Depth;
  3761.         ULONG            MyMode = Mode;
  3762.  
  3763.         if(ReadImageHeader(Handle,&MyMode,&Colours,ColourTable,&BitMapHeader,&TempMandelInfo))
  3764.         {
  3765.             LONG Error;
  3766.  
  3767.             if(TempMandelInfo . Iterations)
  3768.             {
  3769.                 MinReal        = TempMandelInfo . MinReal;
  3770.                 MinImaginary    = TempMandelInfo . MinImaginary;
  3771.                 RealWidth    = TempMandelInfo . RealWidth;
  3772.                 ImaginaryHeight    = TempMandelInfo . ImaginaryHeight;
  3773.  
  3774.                 MaxIteration    = TempMandelInfo . Iterations;
  3775.             }
  3776.  
  3777.             if(BitMapHeader . w == BitMapHeader . h && !(BitMapHeader . h % 4))
  3778.             {
  3779.                 Square    = BitMapHeader . w;
  3780.                 Mode    = MyMode;
  3781.                 Depth    = BitMapHeader . nPlanes;
  3782.             }
  3783.  
  3784.             if(BitMap = CreateBitMap(BitMapHeader . nPlanes,BitMapHeader . w,BitMapHeader . h))
  3785.             {
  3786.                 if(ReadImageBody(Handle,BitMap,&BitMapHeader))
  3787.                     GotImage = TRUE;
  3788.                 else
  3789.                     DeleteBitMap(BitMap);
  3790.             }
  3791.  
  3792.             if(Error = GfxSetup())
  3793.             {
  3794.                 if(GotImage)
  3795.                     DeleteBitMap(BitMap);
  3796.  
  3797.                 CloseImageFile(Handle);
  3798.  
  3799.                 CloseAll(Error);
  3800.             }
  3801.             else
  3802.             {
  3803.                 if(GotImage)
  3804.                 {
  3805.                     BltBitMapRastPort(BitMap,0,0,RPort,0,0,Screen -> Width,Screen -> Height,0xC0);
  3806.  
  3807.                     DeleteBitMap(BitMap);
  3808.                 }
  3809.             }
  3810.  
  3811.             IterationSetup();
  3812.         }
  3813.  
  3814.         CloseImageFile(Handle);
  3815.     }
  3816.     else
  3817.     {
  3818.         struct Rectangle    DisplayClip;
  3819.         LONG            Error,Height;
  3820.  
  3821.             /* No title image, so let's produce one.
  3822.              * At first determine the maximum screen
  3823.              * size.
  3824.              */
  3825.  
  3826.         if(QueryOverscan(Mode,&DisplayClip,OSCAN_TEXT))
  3827.         {
  3828.             WORD p = 0;
  3829.  
  3830.             Height    = (((DisplayClip . MaxY - DisplayClip . MinY + 1) + 3) >> 2) << 2;
  3831.             Square    = 0;
  3832.  
  3833.             while(Square < Height)
  3834.             {
  3835.                 p++;
  3836.  
  3837.                 Square += PLUS;
  3838.             }
  3839.  
  3840.             if(Square > Height)
  3841.             {
  3842.                 p--;
  3843.  
  3844.                 Square -= PLUS;
  3845.             }
  3846.  
  3847.             if(p & 1)
  3848.                 Square -= PLUS;
  3849.         }
  3850.         else
  3851.         {
  3852.             if(Mode == LORES_KEY)
  3853.                 Square = 256;
  3854.             else
  3855.                 Square = 512;
  3856.         }
  3857.  
  3858.         if(Error = GfxSetup())
  3859.             CloseAll(Error);
  3860.     }
  3861.  
  3862.         /* Are we supposed to load and replay an animation file? */
  3863.  
  3864.     if(IsAnim)
  3865.     {
  3866.         BPTR File;
  3867.  
  3868.         SetWait(Window);
  3869.  
  3870.         Window -> Flags |= WFLG_RMBTRAP;
  3871.  
  3872.         if(File = Open(DummyBuffer,MODE_OLDFILE))
  3873.         {
  3874.             if(CreateBuffer())
  3875.             {
  3876.                 if(OpenPreLoadIFF(File))
  3877.                 {
  3878.                     strcpy(AnimPlayName,DummyBuffer);
  3879.  
  3880.                     SetClear(Window);
  3881.  
  3882.                     SwapBits();
  3883.  
  3884.                     ActivateWindow(Window);
  3885.  
  3886.                     ScreenToFront(Screen);
  3887.  
  3888.                     while(PlayAnim());
  3889.  
  3890.                     ClosePreLoadIFF();
  3891.                 }
  3892.  
  3893.                 DeleteBuffer();
  3894.  
  3895.                 LoadRGB4(&Screen -> ViewPort,ColourTable,1 << Depth);
  3896.             }
  3897.  
  3898.             Close(File);
  3899.         }
  3900.  
  3901.         Window -> Flags &= ~WFLG_RMBTRAP;
  3902.  
  3903.         ClearPointer(Window);
  3904.     }
  3905.     else
  3906.     {
  3907.         if(!GotImage)
  3908.         {
  3909.                 /* Set up working data. */
  3910.  
  3911.             MainMinReal        = MinReal;
  3912.             MainMinImaginary    = MinImaginary;
  3913.             MainRealWidth        = RealWidth;
  3914.             MainImaginaryHeight    = ImaginaryHeight;
  3915.  
  3916.                 /* Present the screen. */
  3917.  
  3918.             LoadRGB4(&Screen -> ViewPort,ColourTable,1 << Depth);
  3919.  
  3920.             ScreenToFront(Screen);
  3921.  
  3922.             ActivateWindow(Window);
  3923.  
  3924.             Running        = TRUE;
  3925.             NewCoords    = FALSE;
  3926.  
  3927.                 /* Generate the image. */
  3928.  
  3929.             RunMandelbrot(MinReal,MinReal + RealWidth,MinImaginary,MinImaginary + ImaginaryHeight,Window -> Width,Window -> Height);
  3930.         }
  3931.         else
  3932.         {
  3933.             strcpy(LastName,DummyBuffer);
  3934.  
  3935.                 /* Present the screen. */
  3936.  
  3937.             ScreenToFront(Screen);
  3938.  
  3939.             BlockWindow();
  3940.  
  3941.             ActivateWindow(Window);
  3942.  
  3943.                 /* Fade in the image. */
  3944.  
  3945.             FadeTo(&Screen -> ViewPort,NULL,ColourTable,1 << Depth,0,0);
  3946.  
  3947.             ReleaseWindow();
  3948.         }
  3949.  
  3950.         RealStep    = (RealWidth) / (double)Window -> Width;
  3951.         ImaginaryStep    = (ImaginaryHeight) / (double)Window -> Height;
  3952.     }
  3953.  
  3954.         /* The main input loop. */
  3955.  
  3956.     FOREVER
  3957.     {
  3958.         WaitPort(Window -> UserPort);
  3959.  
  3960.         HandleEvent();
  3961.  
  3962.             /* New display mode? */
  3963.  
  3964.         if(NewMode)
  3965.         {
  3966.             struct Rectangle    DisplayClip;
  3967.             LONG            Error,Height;
  3968.  
  3969.                 /* Remember colour table. */
  3970.  
  3971.             CopyMem(ColourTable,SinPalette,sizeof(UWORD) * 32);
  3972.  
  3973.                 /* We have a bitmap to copy to the
  3974.                  * screen.
  3975.                  */
  3976.  
  3977.             if(GlobalBitMap)
  3978.             {
  3979.                 GfxCleanup();
  3980.  
  3981.                 Mode    = GlobalMode;
  3982.                 Depth    = GlobalHeader . nPlanes;
  3983.                 Square    = GlobalHeader . w;
  3984.  
  3985.                 NewMode    = FALSE;
  3986.  
  3987.                 if(Error = GfxSetup())
  3988.                     CloseAll(Error);
  3989.                 else
  3990.                 {
  3991.                     BltBitMapRastPort(GlobalBitMap,0,0,RPort,0,0,Screen -> Width,Screen -> Height,0xC0);
  3992.  
  3993.                     DeleteBitMap(GlobalBitMap);
  3994.  
  3995.                     GlobalBitMap = NULL;
  3996.  
  3997.                     ScreenToFront(Screen);
  3998.  
  3999.                     BlockWindow();
  4000.  
  4001.                     ActivateWindow(Window);
  4002.  
  4003.                     if(UseWheel)
  4004.                         FadeTo(&Screen -> ViewPort,NULL,WheelPalette,1 << Depth,0,0);
  4005.                     else
  4006.                         FadeTo(&Screen -> ViewPort,NULL,SinPalette,1 << Depth,0,0);
  4007.  
  4008.                     NewCoords    = FALSE;
  4009.                     Running        = FALSE;
  4010.                     AreaActive    = FALSE;
  4011.  
  4012.                     IterationSetup();
  4013.  
  4014.                     ReleaseWindow();
  4015.                 }
  4016.             }
  4017.             else
  4018.             {
  4019.                     /* Open new screen with maximum
  4020.                      * available text overscan dimensions.
  4021.                      */
  4022.  
  4023.                 if(Mode == LORES_KEY)
  4024.                 {
  4025.                     Mode    = HIRESLACE_KEY;
  4026.                     Depth    = 4;
  4027.                 }
  4028.                 else
  4029.                 {
  4030.                     Mode    = LORES_KEY;
  4031.                     Depth    = 5;
  4032.                 }
  4033.  
  4034.                 if(QueryOverscan(Mode,&DisplayClip,OSCAN_TEXT))
  4035.                 {
  4036.                     WORD p = 0;
  4037.  
  4038.                     Height    = (((DisplayClip . MaxY - DisplayClip . MinY + 1) + 3) >> 2) << 2;
  4039.                     Square    = 0;
  4040.  
  4041.                     while(Square < Height)
  4042.                     {
  4043.                         p++;
  4044.  
  4045.                         Square += PLUS;
  4046.                     }
  4047.  
  4048.                     if(Square > Height)
  4049.                     {
  4050.                         p--;
  4051.  
  4052.                         Square -= PLUS;
  4053.                     }
  4054.  
  4055.                     if(p & 1)
  4056.                         Square -= PLUS;
  4057.                 }
  4058.                 else
  4059.                 {
  4060.                     if(Mode == LORES_KEY)
  4061.                         Square = 256;
  4062.                     else
  4063.                         Square = 512;
  4064.                 }
  4065.  
  4066.                 NewMode    = FALSE;
  4067.  
  4068.                 GfxCleanup();
  4069.  
  4070.                 if(Error = GfxSetup())
  4071.                     CloseAll(Error);
  4072.                 else
  4073.                 {
  4074.                     if(UseWheel)
  4075.                         LoadRGB4(&Screen -> ViewPort,WheelPalette,1 << Depth);
  4076.                     else
  4077.                         LoadRGB4(&Screen -> ViewPort,SinPalette,1 << Depth);
  4078.  
  4079.                     ScreenToFront(Screen);
  4080.  
  4081.                     ActivateWindow(Window);
  4082.  
  4083.                     MinReal        = MainMinReal;
  4084.                     MinImaginary    = MainMinImaginary;
  4085.                     RealWidth    = MainRealWidth;
  4086.                     ImaginaryHeight    = MainImaginaryHeight;
  4087.  
  4088.                     RealStep    = (RealWidth) / (double)Window -> Width;
  4089.                     ImaginaryStep    = (ImaginaryHeight) / (double)Window -> Height;
  4090.  
  4091.                     NewCoords    = TRUE;
  4092.                     AreaActive    = FALSE;
  4093.  
  4094.                     IterationSetup();
  4095.                 }
  4096.             }
  4097.         }
  4098.  
  4099.             /* Run the animation routine? */
  4100.  
  4101.         while(AnimRunning)
  4102.         {
  4103.             RunAnim();
  4104.  
  4105.             if(!AnimRunning)
  4106.             {
  4107.                 Running        = FALSE;
  4108.                 NewCoords    = FALSE;
  4109.             }
  4110.         }
  4111.  
  4112.             /* Restart with new coordinates. */
  4113.  
  4114.         if(NewCoords)
  4115.         {
  4116.             Running        = TRUE;
  4117.             NewCoords    = FALSE;
  4118.         }
  4119.  
  4120.             /* Run the image generation routines. */
  4121.  
  4122.         if(Running)
  4123.         {
  4124.             if(AreaActive)
  4125.                 RunAreaMandelbrot(RealStep,ImaginaryStep);
  4126.             else
  4127.             {
  4128.                 SetRast(RPort,0);
  4129.  
  4130.                 RunMandelbrot(MinReal,MinReal + RealWidth,MinImaginary,MinImaginary + ImaginaryHeight,Window -> Width,Window -> Height);
  4131.             }
  4132.         }
  4133.     }
  4134. }
  4135.